diff --git a/.idea/modules.xml b/.idea/modules.xml index 327bffd348..8a1bd10f31 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -21,6 +21,7 @@ + diff --git a/build.gradle b/build.gradle index 6af144aef3..0f15cbaa33 100644 --- a/build.gradle +++ b/build.gradle @@ -1,11 +1,11 @@ -group 'com.r3cev.prototyping' -version '1.0-SNAPSHOT' +group 'com.r3corda' apply plugin: 'java' apply plugin: 'kotlin' apply plugin: 'application' apply plugin: 'project-report' apply plugin: QuasarPlugin +apply plugin: 'com.github.ben-manes.versions' allprojects { sourceCompatibility = 1.8 @@ -17,13 +17,16 @@ allprojects { } buildscript { - ext.kotlin_version = '1.0.2' + ext.kotlin_version = '1.0.3' ext.quasar_version = '0.7.5' ext.asm_version = '0.5.3' ext.artemis_version = '1.3.0' - ext.jetty_version = '9.1.1.v20140108' - ext.jersey_version = '2.22.2' + ext.jackson_version = '2.8.0.rc2' + ext.jetty_version = '9.3.9.v20160517' + ext.jersey_version = '2.23.1' ext.jolokia_version = '2.0.0-M1' + ext.slf4j_version = '1.7.21' + ext.assertj_version = '3.5.1' repositories { mavenCentral() @@ -31,9 +34,17 @@ buildscript { } dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" + + // Can run 'gradle dependencyUpdates' to find new versions of things. + classpath 'com.github.ben-manes:gradle-versions-plugin:0.12.0' } } +allprojects { + // Our version: bump this on release. + group 'com.r3corda' + version '0.2-SNAPSHOT' +} repositories { mavenLocal() @@ -44,10 +55,23 @@ repositories { jcenter() } +sourceSets { + integrationTest { + kotlin { + compileClasspath += main.output + test.output + runtimeClasspath += main.output + test.output + srcDir file('src/integration-test/kotlin') + } + } +} + //noinspection GroovyAssignabilityCheck configurations { // we don't want isolated.jar in classPath, since we want to test jar being dynamically loaded as an attachment runtime.exclude module: 'isolated' + + integrationTestCompile.extendsFrom testCompile + integrationTestRuntime.extendsFrom testRuntime } // This is required for quasar. I think. @@ -64,12 +88,17 @@ dependencies { compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" - compile "org.jetbrains.kotlinx:kotlinx-support-jdk8:0.1" + compile "org.jetbrains.kotlinx:kotlinx-support-jdk8:0.2" + compile 'com.squareup.okhttp3:okhttp:3.3.1' // Unit testing helpers. testCompile 'junit:junit:4.12' testCompile 'org.assertj:assertj-core:3.4.1' testCompile 'com.pholser:junit-quickcheck-core:0.6' + + // Integration test helpers + integrationTestCompile 'junit:junit:4.12' + integrationTestCompile 'org.assertj:assertj-core:${assertj_version}' } // Package up the demo programs. @@ -99,8 +128,7 @@ task getTraderDemo(type: CreateStartScripts) { // Force windows script classpath to wildcard path to avoid the 'Command Line Is Too Long' issues // with generated scripts. Include Jolokia .war explicitly as this isn't picked up by wildcard -tasks.withType(CreateStartScripts) -{ +tasks.withType(CreateStartScripts) { doLast { windowsScript.text = windowsScript .readLines() @@ -109,6 +137,16 @@ tasks.withType(CreateStartScripts) } } +task integrationTest(type: Test) { + testClassesDir = sourceSets.integrationTest.output.classesDir + classpath = sourceSets.integrationTest.runtimeClasspath +} +test.finalizedBy(integrationTest) + +tasks.withType(Test) { + reports.html.destination = file("${reporting.baseDir}/${name}") +} + quasarScan.dependsOn('classes', 'core:classes', 'contracts:classes', 'node:classes') applicationDistribution.into("bin") { diff --git a/contracts/src/main/java/com/r3corda/contracts/JavaCommercialPaper.java b/contracts/src/main/java/com/r3corda/contracts/JavaCommercialPaper.java index a1ba26e559..5b37c86887 100644 --- a/contracts/src/main/java/com/r3corda/contracts/JavaCommercialPaper.java +++ b/contracts/src/main/java/com/r3corda/contracts/JavaCommercialPaper.java @@ -1,9 +1,9 @@ package com.r3corda.contracts; import com.google.common.collect.ImmutableList; -import com.r3corda.contracts.cash.Cash; -import com.r3corda.contracts.cash.CashKt; -import com.r3corda.contracts.cash.InsufficientBalanceException; +import com.r3corda.contracts.asset.Cash; +import com.r3corda.contracts.asset.CashKt; +import com.r3corda.contracts.asset.InsufficientBalanceException; import com.r3corda.core.contracts.*; import com.r3corda.core.contracts.TransactionForContract.InOutGroup; import com.r3corda.core.crypto.NullPublicKey; diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/CommercialPaper.kt b/contracts/src/main/kotlin/com/r3corda/contracts/CommercialPaper.kt index eabb650386..27d41a59df 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/CommercialPaper.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/CommercialPaper.kt @@ -1,8 +1,8 @@ package com.r3corda.contracts -import com.r3corda.contracts.cash.Cash -import com.r3corda.contracts.cash.InsufficientBalanceException -import com.r3corda.contracts.cash.sumCashBy +import com.r3corda.contracts.asset.Cash +import com.r3corda.contracts.asset.InsufficientBalanceException +import com.r3corda.contracts.asset.sumCashBy import com.r3corda.core.contracts.* import com.r3corda.core.crypto.NullPublicKey import com.r3corda.core.crypto.Party diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt b/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt index cc09c7d657..33c2c0bb2d 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/IRS.kt @@ -3,6 +3,9 @@ package com.r3corda.contracts import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash +import com.r3corda.core.protocols.ProtocolLogicRefFactory +import com.r3corda.core.utilities.suggestInterestRateAnnouncementTimeWindow +import com.r3corda.protocols.TwoPartyDealProtocol import org.apache.commons.jexl3.JexlBuilder import org.apache.commons.jexl3.MapContext import java.math.BigDecimal @@ -588,7 +591,7 @@ class InterestRateSwap() : Contract { val floatingLeg: FloatingLeg, val calculation: Calculation, val common: Common - ) : FixableDealState { + ) : FixableDealState, SchedulableState { override val contract = IRS_PROGRAM_ID override val thread = SecureHash.sha256(common.tradeID) @@ -604,6 +607,14 @@ class InterestRateSwap() : Contract { override val parties: Array get() = arrayOf(fixedLeg.fixedRatePayer, floatingLeg.floatingRatePayer) + override fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity? { + val nextFixingOf = nextFixingOf() ?: return null + + // This is perhaps not how we should determine the time point in the business day, but instead expect the schedule to detail some of these aspects + val (instant, duration) = suggestInterestRateAnnouncementTimeWindow(index = nextFixingOf.name, source = floatingLeg.indexSource, date = nextFixingOf.forDay) + return ScheduledActivity(protocolLogicRefFactory.create(TwoPartyDealProtocol.FixingRoleDecider::class.java, thisStateRef, duration), instant) + } + // TODO: This changing of the public key violates the assumption that Party is a fixed identity key. override fun withPublicKey(before: Party, after: PublicKey): DealState { val newParty = Party(before.name, after) diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt b/contracts/src/main/kotlin/com/r3corda/contracts/asset/Cash.kt similarity index 95% rename from contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt rename to contracts/src/main/kotlin/com/r3corda/contracts/asset/Cash.kt index 2d15cebd7e..446e90f8c2 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/cash/Cash.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/asset/Cash.kt @@ -1,4 +1,4 @@ -package com.r3corda.contracts.cash +package com.r3corda.contracts.asset import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party @@ -54,6 +54,9 @@ class Cash : FungibleAsset() { ) : FungibleAsset.State { constructor(deposit: PartyAndReference, amount: Amount, owner: PublicKey) : this(Amount(amount.quantity, Issued(deposit, amount.token)), owner) + + override val productAmount: Amount + get() = Amount(amount.quantity, amount.token.product) override val deposit: PartyAndReference get() = amount.token.issuer override val contract = CASH_PROGRAM_ID @@ -62,8 +65,8 @@ class Cash : FungibleAsset() { override val participants: List get() = listOf(owner) - override fun move(amount: Amount>, owner: PublicKey): FungibleAsset.State - = copy(amount = amount, owner = owner) + override fun move(newAmount: Amount, newOwner: PublicKey): FungibleAsset.State + = copy(amount = amount.copy(newAmount.quantity, amount.token), owner = newOwner) override fun toString() = "${Emoji.bagOfCash}Cash($amount at $deposit owned by ${owner.toStringShort()})" @@ -75,9 +78,9 @@ class Cash : FungibleAsset() { /** * A command stating that money has been moved, optionally to fulfil another contract. * - * @param contractHash the hash of the contract this cash is settling, to ensure one cash contract cannot be - * used to settle multiple contracts. May be null, if this is not relevant to any other contract in the - * same transaction + * @param contractHash the contract this move is for the attention of. Only that contract's verify function + * should take the moved states into account when considering whether it is valid. Typically this will be + * null. */ data class Move(override val contractHash: SecureHash? = null) : FungibleAsset.Commands.Move, Commands diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt b/contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAsset.kt similarity index 98% rename from contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt rename to contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAsset.kt index 56061adab2..59ae41fdbc 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAsset.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAsset.kt @@ -1,4 +1,4 @@ -package com.r3corda.contracts.cash +package com.r3corda.contracts.asset import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party @@ -34,7 +34,7 @@ abstract class FungibleAsset : Contract { interface State : FungibleAssetState> { /** Where the underlying currency backing this ledger entry can be found (propagated) */ val deposit: PartyAndReference - override val amount: Amount> + val amount: Amount> /** There must be a MoveCommand signed by this key to claim the amount */ override val owner: PublicKey } diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAssetState.kt b/contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAssetState.kt similarity index 65% rename from contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAssetState.kt rename to contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAssetState.kt index 17fa51adb2..436919b690 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/cash/FungibleAssetState.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/asset/FungibleAssetState.kt @@ -1,4 +1,4 @@ -package com.r3corda.contracts.cash +package com.r3corda.contracts.asset import com.r3corda.core.contracts.Amount import com.r3corda.core.contracts.Issued @@ -10,6 +10,6 @@ import java.security.PublicKey */ interface FungibleAssetState : OwnableState { val issuanceDef: I - val amount: Amount> - fun move(amount: Amount>, owner: PublicKey): FungibleAssetState + val productAmount: Amount + fun move(newAmount: Amount, newOwner: PublicKey): FungibleAssetState } \ No newline at end of file diff --git a/experimental/src/main/kotlin/com/r3corda/contracts/Obligation.kt b/contracts/src/main/kotlin/com/r3corda/contracts/asset/Obligation.kt similarity index 63% rename from experimental/src/main/kotlin/com/r3corda/contracts/Obligation.kt rename to contracts/src/main/kotlin/com/r3corda/contracts/asset/Obligation.kt index 3635785735..1aa3538461 100644 --- a/experimental/src/main/kotlin/com/r3corda/contracts/Obligation.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/asset/Obligation.kt @@ -1,7 +1,8 @@ -package com.r3corda.contracts +package com.r3corda.contracts.asset import com.google.common.annotations.VisibleForTesting -import com.r3corda.contracts.cash.* +import com.r3corda.contracts.asset.FungibleAssetState +import com.r3corda.contracts.asset.sumFungibleOrNull import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash @@ -18,12 +19,10 @@ import java.util.* val OBLIGATION_PROGRAM_ID = Obligation() /** - * A cash settlement contract commits the issuer to delivering a specified amount of cash (represented as the [Cash] - * contract) at a specified future point in time. Similarly to cash, settlement transactions may split and merge - * contracts across multiple input and output states. - * - * The goal of this design is to handle money owed, and these contracts are expected to be netted/merged, with - * settlement only for any remainder amount. + * An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the + * [Cash] contract) at a specified future point in time. Settlement transactions may split and merge contracts across + * multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected + * to be netted/merged, with settlement only for any remainder amount. * * @param P the product the obligation is for payment of. */ @@ -51,7 +50,7 @@ class Obligation

: Contract { NORMAL, /** * Indicates the contract has not been settled by its due date. Once in the defaulted state, - * it can only be reverted to [NORMAL] state by the owner. + * it can only be reverted to [NORMAL] state by the beneficiary. */ DEFAULTED } @@ -61,7 +60,7 @@ class Obligation

: Contract { * underlying issued thing. */ interface NetState

{ - val issued: Issued

+ val template: StateTemplate

} /** @@ -71,11 +70,8 @@ class Obligation

: Contract { */ data class BilateralNetState

( val partyKeys: Set, - val issuanceDef: StateTemplate

- ) : NetState

{ - override val issued: Issued

- get() = issuanceDef.issued - } + override val template: StateTemplate

+ ) : NetState

/** * Subset of state, containing the elements which must match for two or more obligation transactions to be candidates @@ -86,11 +82,8 @@ class Obligation

: Contract { * Used in cases where all parties (or their proxies) are signing, such as central clearing. */ data class MultilateralNetState

( - val issuanceDef: StateTemplate

- ) : NetState

{ - override val issued: Issued

- get() = issuanceDef.issued - } + override val template: StateTemplate

+ ) : NetState

/** * Subset of state, containing the elements specified when issuing a new settlement contract. @@ -98,17 +91,17 @@ class Obligation

: Contract { * @param P the product the obligation is for payment of. */ data class StateTemplate

( - /** The hash of the cash contract we're willing to accept in payment for this debt. */ + /** The hash of the asset contract we're willing to accept in payment for this debt. */ val acceptableContracts: NonEmptySet, - /** The parties whose cash we are willing to accept in payment for this debt. */ - val acceptableIssuanceDefinitions: NonEmptySet>, + /** The parties whose assets we are willing to accept in payment for this debt. */ + val acceptableIssuedProducts: NonEmptySet>, /** When the contract must be settled by. */ val dueBefore: Instant, val timeTolerance: Duration = Duration.ofSeconds(30) ) { - val issued: Issued

- get() = acceptableIssuanceDefinitions.toSet().single() + val product: P + get() = acceptableIssuedProducts.map { it.product }.toSet().single() } /** @@ -119,57 +112,58 @@ class Obligation

: Contract { * @param P the product the obligation is for payment of. */ data class IssuanceDefinition

( - val issuer: Party, + val obligor: Party, val template: StateTemplate

- ) { - val currency: P - get() = template.issued.product - val issued: Issued

- get() = template.issued - } + ) /** - * A state representing the obligation of one party (issuer) to deliver a specified number of - * units of an underlying asset (described as issuanceDef.acceptableCashIssuance) to the owner + * A state representing the obligation of one party (obligor) to deliver a specified number of + * units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary * no later than the specified time. * * @param P the product the obligation is for payment of. */ data class State

( var lifecycle: Lifecycle = Lifecycle.NORMAL, - /** Where the debt originates from (issuer) */ - val issuer: Party, + /** Where the debt originates from (obligor) */ + val obligor: Party, val template: StateTemplate

, val quantity: Long, /** The public key of the entity the contract pays to */ - override val owner: PublicKey + val beneficiary: PublicKey ) : FungibleAssetState>, BilateralNettableState> { - override val amount: Amount> - get() = Amount(quantity, template.issued) + val amount: Amount

+ get() = Amount(quantity, template.product) + val aggregateState: IssuanceDefinition

+ get() = issuanceDef + override val productAmount: Amount

+ get() = amount override val contract = OBLIGATION_PROGRAM_ID val acceptableContracts: NonEmptySet get() = template.acceptableContracts val acceptableIssuanceDefinitions: NonEmptySet<*> - get() = template.acceptableIssuanceDefinitions + get() = template.acceptableIssuedProducts val dueBefore: Instant get() = template.dueBefore override val issuanceDef: IssuanceDefinition

- get() = IssuanceDefinition(issuer, template) + get() = IssuanceDefinition(obligor, template) override val participants: List - get() = listOf(issuer.owningKey, owner) + get() = listOf(obligor.owningKey, beneficiary) + override val owner: PublicKey + get() = beneficiary - override fun move(amount: Amount>, owner: PublicKey): Obligation.State

- = copy(quantity = amount.quantity, owner = owner) + override fun move(newAmount: Amount

, newOwner: PublicKey): State

+ = copy(quantity = newAmount.quantity, beneficiary = newOwner) override fun toString() = when (lifecycle) { - Lifecycle.NORMAL -> "${Emoji.bagOfCash}Debt($amount due $dueBefore to ${owner.toStringShort()})" - Lifecycle.DEFAULTED -> "${Emoji.bagOfCash}Debt($amount unpaid by $dueBefore to ${owner.toStringShort()})" + Lifecycle.NORMAL -> "${Emoji.bagOfCash}Debt($amount due $dueBefore to ${beneficiary.toStringShort()})" + Lifecycle.DEFAULTED -> "${Emoji.bagOfCash}Debt($amount unpaid by $dueBefore to ${beneficiary.toStringShort()})" } override val bilateralNetState: BilateralNetState

get() { check(lifecycle == Lifecycle.NORMAL) - return BilateralNetState(setOf(issuer.owningKey, owner), template) + return BilateralNetState(setOf(obligor.owningKey, beneficiary), template) } val multilateralNetState: MultilateralNetState

get() { @@ -182,78 +176,83 @@ class Obligation

: Contract { val netB = other.bilateralNetState require(netA == netB) { "net substates of the two state objects must be identical" } - if (issuer.owningKey == other.issuer.owningKey) { - // Both sides are from the same issuer to owner + if (obligor.owningKey == other.obligor.owningKey) { + // Both sides are from the same obligor to beneficiary return copy(quantity = quantity + other.quantity) } else { - // Issuer and owner are backwards + // Issuer and beneficiary are backwards return copy(quantity = quantity - other.quantity) } } - override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(issuanceDef), copy(owner = newOwner)) + override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(issuanceDef), copy(beneficiary = newOwner)) } - /** Interface for commands that apply to aggregated states */ - interface AggregateCommands

: CommandData { + /** Interface for commands that apply to states grouped by issuance definition */ + interface IssuanceCommands

: CommandData { val aggregateState: IssuanceDefinition

} // Just for grouping interface Commands : CommandData { /** - * Net two or more cash settlement states together in a close-out netting style. Limited to bilateral netting - * as only the owner (not the issuer) needs to sign. + * Net two or more obligation states together in a close-out netting style. Limited to bilateral netting + * as only the beneficiary (not the obligor) needs to sign. */ data class Net(val type: NetType) : Commands /** * A command stating that a debt has been moved, optionally to fulfil another contract. * - * @param contractHash the hash of contract's code, which indicates to that contract that the - * obligation states moved in this transaction are for their sole attention. - * This is a single value to ensure the same state(s) cannot be used to settle multiple contracts. - * May be null, if this is not relevant to any other contract in the same transaction. + * @param contractHash the contract this move is for the attention of. Only that contract's verify function + * should take the moved states into account when considering whether it is valid. Typically this will be + * null. */ data class Move

(override val aggregateState: IssuanceDefinition

, - override val contractHash: SecureHash? = null) : Commands, AggregateCommands

, MoveCommand + override val contractHash: SecureHash? = null) : Commands, IssuanceCommands

, MoveCommand /** - * Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction - * has a unique ID even when there are no inputs. + * Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the + * transaction has a unique ID even when there are no inputs. */ data class Issue

(override val aggregateState: IssuanceDefinition

, - val nonce: Long = random63BitValue()) : Commands, AggregateCommands

+ val nonce: Long = random63BitValue()) : Commands, IssuanceCommands

/** - * A command stating that the issuer is settling some or all of the amount owed by paying in a suitable cash - * contract. If this reduces the balance to zero, the contract moves to the settled state. - * @see [Cash.Commands.Move] + * A command stating that the obligor is settling some or all of the amount owed by transferring a suitable + * state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed. + * @see [MoveCommand] */ data class Settle

(override val aggregateState: IssuanceDefinition

, - val amount: Amount>) : Commands, AggregateCommands

+ val amount: Amount

) : Commands, IssuanceCommands

/** - * A command stating that the owner is moving the contract into the defaulted state as it has not been settled + * A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled * by the due date, or resetting a defaulted contract back to the issued state. */ data class SetLifecycle

(override val aggregateState: IssuanceDefinition

, - val lifecycle: Lifecycle) : Commands, AggregateCommands

+ val lifecycle: Lifecycle) : Commands, IssuanceCommands

{ + val inverse: Lifecycle + get() = when (lifecycle) { + Lifecycle.NORMAL -> Lifecycle.DEFAULTED + Lifecycle.DEFAULTED -> Lifecycle.NORMAL + } + } /** - * A command stating that the debt is being released by the owner. Normally would indicate - * either settlement outside of the ledger, or that the issuer is unable to pay. + * A command stating that the debt is being released by the beneficiary. Normally would indicate + * either settlement outside of the ledger, or that the obligor is unable to pay. */ data class Exit

(override val aggregateState: IssuanceDefinition

, - val amount: Amount>) : Commands, AggregateCommands

+ val amount: Amount

) : Commands, IssuanceCommands

} /** This is the function EVERYONE runs */ override fun verify(tx: TransactionForContract) { - val commands = tx.commands.select() + val commands = tx.commands.select() // Net commands are special, and cross issuance definitions, so handle them first - val netCommands = commands.select() + val netCommands = commands.select() if (netCommands.isNotEmpty()) { val netCommand = netCommands.single() val groups = when (netCommand.value.type) { @@ -264,40 +263,39 @@ class Obligation

: Contract { verifyNetCommand(inputs, outputs, netCommand, key) } } else { - val commandGroups = tx.groupCommands, IssuanceDefinition

> { it.value.aggregateState } + val commandGroups = tx.groupCommands, IssuanceDefinition

> { it.value.aggregateState } // Each group is a set of input/output states with distinct issuance definitions. These types // of settlement are not fungible and must be kept separated for bookkeeping purposes. - val groups = tx.groupStates() { it: State

-> it.issuanceDef } + val groups = tx.groupStates() { it: State

-> it.aggregateState } for ((inputs, outputs, key) in groups) { // Either inputs or outputs could be empty. - val issuer = key.issuer - val commands = commandGroups[key] ?: emptyList() + val obligor = key.obligor requireThat { "there are no zero sized outputs" by outputs.none { it.amount.quantity == 0L } } - verifyCommandGroup(tx, commands, inputs, outputs, issuer, key) + verifyCommandGroup(tx, commandGroups[key] ?: emptyList(), inputs, outputs, obligor, key) } } } private fun verifyCommandGroup(tx: TransactionForContract, - commands: List>>, + commands: List>>, inputs: List>, outputs: List>, - issuer: Party, + obligor: Party, key: IssuanceDefinition

) { - // We've already pre-grouped by currency amongst other fields, and verified above that every state specifies - // at least one acceptable cash issuance definition, so we can just use the first issuance definition to - // determine currency - val currency = key.template.acceptableIssuanceDefinitions.first() + // We've already pre-grouped by product amongst other fields, and verified above that every state specifies + // at least one acceptable issuance definition, so we can just use the first issuance definition to + // determine product + val issued = key.template.acceptableIssuedProducts.first() // Issue, default, net and settle commands are all single commands (there's only ever one of them, and // they exclude all other commands). val issueCommand = commands.select>().firstOrNull() - val defaultCommand = commands.select>().firstOrNull() + val setLifecycleCommand = commands.select>().firstOrNull() val settleCommand = commands.select>().firstOrNull() if (commands.size != 1) { @@ -308,8 +306,8 @@ class Obligation

: Contract { // Issue, default and net commands are special, and do not follow normal input/output summing rules, so // deal with them first - if (defaultCommand != null) { - verifyDefaultCommand(inputs, outputs, tx, defaultCommand) + if (setLifecycleCommand != null) { + verifySetLifecycleCommand(inputs, outputs, tx, setLifecycleCommand) } else { // Only the default command processes inputs/outputs that are not in the normal state // TODO: Need to be able to exit defaulted amounts @@ -318,15 +316,15 @@ class Obligation

: Contract { "all outputs are in the normal state " by outputs.all { it.lifecycle == Lifecycle.NORMAL } } if (issueCommand != null) { - verifyIssueCommand(inputs, outputs, tx, issueCommand, currency, issuer) + verifyIssueCommand(inputs, outputs, issueCommand, issued, obligor) } else if (settleCommand != null) { // Perhaps through an abundance of caution, settlement is enforced as its own command. // This could perhaps be merged into verifyBalanceChange() later, however doing so introduces a lot // of scope for making it more opaque what's going on in a transaction and whether it's as expected // by all parties. - verifySettleCommand(inputs, outputs, tx, settleCommand, currency, issuer, key) + verifySettleCommand(inputs, outputs, tx, settleCommand, issued, obligor, key) } else { - verifyBalanceChange(inputs, outputs, commands, currency, issuer) + verifyBalanceChange(inputs, outputs, commands, issued.product, obligor) } } } @@ -339,32 +337,32 @@ class Obligation

: Contract { */ private fun verifyBalanceChange(inputs: List>, outputs: List>, - commands: List>>, - currency: Issued

, - issuer: Party) { + commands: List>>, + product: P, + obligor: Party) { // Sum up how much settlement owed there is in the inputs, and the difference in outputs. The difference should // be matched by exit commands representing the extracted amount. val inputAmount = inputs.sumObligationsOrNull

() ?: throw IllegalArgumentException("there is at least one obligation input for this group") - val outputAmount = outputs.sumObligationsOrZero(currency) + val outputAmount = outputs.sumObligationsOrZero(product) val exitCommands = commands.select>() val requiredExitSignatures = HashSet() - val amountExitingLedger: Amount> = if (exitCommands.isNotEmpty()) { + val amountExitingLedger: Amount

= if (exitCommands.isNotEmpty()) { require(exitCommands.size == 1) { "There can only be one exit command" } val exitCommand = exitCommands.single() - // If we want to remove debt from the ledger, that must be signed for by the owner. For now we require exit - // commands to be signed by all input owners, unlocking the full input amount, rather than trying to detangle + // If we want to remove debt from the ledger, that must be signed for by the beneficiary. For now we require exit + // commands to be signed by all input beneficiarys, unlocking the full input amount, rather than trying to detangle // exactly who exited what. - requiredExitSignatures.addAll(inputs.map { it.owner }) + requiredExitSignatures.addAll(inputs.map { it.beneficiary }) exitCommand.value.amount } else { - Amount(0, currency) + Amount(0, product) } requireThat { "there are no zero sized inputs" by inputs.none { it.amount.quantity == 0L } - "at issuer ${issuer.name} the amounts balance" by + "at obligor ${obligor.name} the amounts balance" by (inputAmount == outputAmount + amountExitingLedger) } @@ -375,39 +373,36 @@ class Obligation

: Contract { * A default command mutates inputs and produces identical outputs, except that the lifecycle changes. */ @VisibleForTesting - protected fun verifyDefaultCommand(inputs: List>, - outputs: List>, - tx: TransactionForContract, - setLifecycleCommand: AuthenticatedObject>) { + protected fun verifySetLifecycleCommand(inputs: List>, + outputs: List>, + tx: TransactionForContract, + setLifecycleCommand: AuthenticatedObject>) { // Default must not change anything except lifecycle, so number of inputs and outputs must match // exactly. require(inputs.size == outputs.size) { "Number of inputs and outputs must match" } // If we have an default command, perform special processing: issued contracts can only be defaulted - // after the due date, and default/reset can only be done by the owner - val expectedOutputState: Lifecycle = setLifecycleCommand.value.lifecycle - val expectedInputState: Lifecycle - - expectedInputState = when (expectedOutputState) { - Lifecycle.DEFAULTED -> Lifecycle.NORMAL - Lifecycle.NORMAL -> Lifecycle.DEFAULTED - } + // after the due date, and default/reset can only be done by the beneficiary + val expectedInputLifecycle: Lifecycle = setLifecycleCommand.value.inverse + val expectedOutputLifecycle: Lifecycle = setLifecycleCommand.value.lifecycle // Check that we're past the deadline for ALL involved inputs, and that the output states correspond 1:1 for ((stateIdx, input) in inputs.withIndex()) { val actualOutput = outputs[stateIdx] val deadline = input.dueBefore + // TODO: Determining correct timestamp authority needs rework now that timestamping service is part of + // notary. val timestamp: TimestampCommand? = tx.commands.getTimestampByName("Mock Company 0", "Notary Service", "Bank A") - val expectedOutput: State

= input.copy(lifecycle = expectedOutputState) + val expectedOutput: State

= input.copy(lifecycle = expectedOutputLifecycle) requireThat { "there is a timestamp from the authority" by (timestamp != null) - "the due date has passed" by (timestamp?.after?.isBefore(deadline) ?: false) - "input state lifecycle is correct" by (input.lifecycle == expectedInputState) + "the due date has passed" by (timestamp!!.after?.isAfter(deadline) ?: false) + "input state lifecycle is correct" by (input.lifecycle == expectedInputLifecycle) "output state corresponds exactly to input state, with lifecycle changed" by (expectedOutput == actualOutput) } } - val owningPubKeys = inputs.map { it.owner }.toSet() + val owningPubKeys = inputs.map { it.beneficiary }.toSet() val keysThatSigned = setLifecycleCommand.signers.toSet() requireThat { "the owning keys are the same as the signing keys" by keysThatSigned.containsAll(owningPubKeys) @@ -417,18 +412,17 @@ class Obligation

: Contract { @VisibleForTesting protected fun verifyIssueCommand(inputs: List>, outputs: List>, - tx: TransactionForContract, issueCommand: AuthenticatedObject>, - currency: Issued

, - issuer: Party) { + issued: Issued

, + obligor: Party) { // If we have an issue command, perform special processing: the group is must have no inputs, - // and that signatures are present for all issuers. + // and that signatures are present for all obligors. - val inputAmount = inputs.sumObligationsOrZero(currency) - val outputAmount = outputs.sumObligations

() + val inputAmount: Amount

= inputs.sumObligationsOrZero(issued.product) + val outputAmount: Amount

= outputs.sumObligations

() requireThat { "the issue command has a nonce" by (issueCommand.value.nonce != 0L) - "output deposits are owned by a command signer" by (issuer in issueCommand.signingParties) + "output deposits are owned by a command signer" by (obligor in issueCommand.signingParties) "output values sum to more than the inputs" by (outputAmount > inputAmount) "valid settlement issuance definition is not this issuance definition" by inputs.none { it.issuanceDef in it.acceptableIssuanceDefinitions } } @@ -448,24 +442,25 @@ class Obligation

: Contract { "all outputs are in the normal state " by outputs.all { it.lifecycle == Lifecycle.NORMAL } } - val token = netState.issued - // Create two maps of balances from issuers to owners, one for input states, the other for output states. - val inputBalances = extractAmountsDue(token, inputs) - val outputBalances = extractAmountsDue(token, outputs) + val template = netState.template + val product = template.product + // Create two maps of balances from obligors to beneficiaries, one for input states, the other for output states. + val inputBalances = extractAmountsDue(product, inputs) + val outputBalances = extractAmountsDue(product, outputs) // Sum the columns of the matrices. This will yield the net amount payable to/from each party to/from all other participants. // The two summaries must match, reflecting that the amounts owed match on both input and output. requireThat { - "all input states use the expected token" by (inputs.all { it.issuanceDef.issued == token }) - "all output states use the expected token" by (outputs.all { it.issuanceDef.issued == token }) + "all input states use the same template" by (inputs.all { it.template == template }) + "all output states use the same template" by (outputs.all { it.template == template }) "amounts owed on input and output must match" by (sumAmountsDue(inputBalances) == sumAmountsDue(outputBalances)) } // TODO: Handle proxies nominated by parties, i.e. a central clearing service - val involvedParties = inputs.map { it.owner }.union(inputs.map { it.issuer.owningKey }).toSet() + val involvedParties = inputs.map { it.beneficiary }.union(inputs.map { it.obligor.owningKey }).toSet() when (command.value.type) { // For close-out netting, allow any involved party to sign - NetType.CLOSE_OUT -> require(involvedParties.intersect(command.signers).isNotEmpty()) { "any involved party has signed" } + NetType.CLOSE_OUT -> require(command.signers.intersect(involvedParties).isNotEmpty()) { "any involved party has signed" } // Require signatures from all parties (this constraint can be changed for other contracts, and is used as a // placeholder while exact requirements are established), or fail the transaction. NetType.PAYMENT -> require(command.signers.containsAll(involvedParties)) { "all involved parties have signed" } @@ -479,20 +474,20 @@ class Obligation

: Contract { outputs: List>, tx: TransactionForContract, command: AuthenticatedObject>, - currency: Issued

, - issuer: Party, + issued: Issued

, + obligor: Party, key: IssuanceDefinition

) { val template = key.template - val inputAmount = inputs.sumObligationsOrNull

() ?: throw IllegalArgumentException("there is at least one obligation input for this group") - val outputAmount = outputs.sumObligationsOrZero(currency) + val inputAmount: Amount

= inputs.sumObligationsOrNull

() ?: throw IllegalArgumentException("there is at least one obligation input for this group") + val outputAmount: Amount

= outputs.sumObligationsOrZero(issued.product) - // Sum up all cash contracts that are moving and fulfil our requirements + // Sum up all asset state objects that are moving and fulfil our requirements - // The cash contract verification handles ensuring there's inputs enough to cover the output states, we only - // care about counting how much cash is output in this transaction. We then calculate the difference in + // The fungible asset contract verification handles ensuring there's inputs enough to cover the output states, + // we only care about counting how much is output in this transaction. We then calculate the difference in // settlement amounts between the transaction inputs and outputs, and the two must match. No elimination is - // done of amounts paid in by each owner, as it's presumed the owners have enough sense to do that themselves. - // Therefore if someone actually signed the following transaction: + // done of amounts paid in by each beneficiary, as it's presumed the beneficiaries have enough sense to do that + // themselves. Therefore if someone actually signed the following transaction (using cash just for an example): // // Inputs: // £1m cash owned by B @@ -500,37 +495,37 @@ class Obligation

: Contract { // Outputs: // £1m cash owned by B // Commands: - // Settle (signed by B) + // Settle (signed by A) // Move (signed by B) // // That would pass this check. Ensuring they do not is best addressed in the transaction generation stage. - val cashStates = tx.outStates.filterIsInstance>() - val acceptableCashStates = cashStates - // TODO: This filter is nonsense, because it just checks there is a cash contract loaded, we need to - // verify the cash contract is the cash contract we expect. + val assetStates = tx.outputs.filterIsInstance>() + val acceptableAssetStates = assetStates + // TODO: This filter is nonsense, because it just checks there is an asset contract loaded, we need to + // verify the asset contract is the asset contract we expect. // Something like: - // attachments.mustHaveOneOf(key.acceptableCashContract) + // attachments.mustHaveOneOf(key.acceptableAssetContract) .filter { it.contract.legalContractReference in template.acceptableContracts } // Restrict the states to those of the correct issuance definition (this normally - // covers currency and issuer, but is opaque to us) - .filter { it.issuanceDef in template.acceptableIssuanceDefinitions } + // covers issued product and obligor, but is opaque to us) + .filter { it.issuanceDef in template.acceptableIssuedProducts } // Catch that there's nothing useful here, so we can dump out a useful error requireThat { - "there are cash state outputs" by (cashStates.size > 0) - "there are defined acceptable cash states" by (acceptableCashStates.size > 0) + "there are fungible asset state outputs" by (assetStates.size > 0) + "there are defined acceptable fungible asset states" by (acceptableAssetStates.size > 0) } - val amountReceivedByOwner = acceptableCashStates.groupBy { it.owner } + val amountReceivedByOwner = acceptableAssetStates.groupBy { it.owner } // Note we really do want to search all commands, because we want move commands of other contracts, not just // this one. val moveCommands = tx.commands.select() var totalPenniesSettled = 0L - val requiredSigners = inputs.map { it.issuer.owningKey }.toSet() + val requiredSigners = inputs.map { it.obligor.owningKey }.toSet() - for ((owner, obligations) in inputs.groupBy { it.owner }) { - val settled = amountReceivedByOwner[owner]?.sumCashOrNull() + for ((beneficiary, obligations) in inputs.groupBy { it.beneficiary }) { + val settled = amountReceivedByOwner[beneficiary]?.sumFungibleOrNull

() if (settled != null) { - val debt = obligations.sumObligationsOrZero(currency) + val debt = obligations.sumObligationsOrZero(issued) require(settled.quantity <= debt.quantity) { "Payment of $settled must not exceed debt $debt" } totalPenniesSettled += settled.quantity } @@ -542,19 +537,19 @@ class Obligation

: Contract { "all move commands relate to this contract" by (moveCommands.map { it.value.contractHash } .all { it == null || it == legalContractReference }) "contract does not try to consume itself" by (moveCommands.map { it.value }.filterIsInstance>() - .none { it.aggregateState.issued in template.acceptableIssuanceDefinitions }) - "amounts paid must match recipients to settle" by inputs.map { it.owner }.containsAll(amountReceivedByOwner.keys) - "signatures are present from all issuers" by command.signers.containsAll(requiredSigners) + .none { it.aggregateState == key }) + "amounts paid must match recipients to settle" by inputs.map { it.beneficiary }.containsAll(amountReceivedByOwner.keys) + "signatures are present from all obligors" by command.signers.containsAll(requiredSigners) "there are no zero sized inputs" by inputs.none { it.amount.quantity == 0L } - "at issuer ${issuer.name} the obligations after settlement balance" by - (inputAmount == outputAmount + Amount(totalPenniesSettled, currency)) + "at obligor ${obligor.name} the obligations after settlement balance" by + (inputAmount == outputAmount + Amount(totalPenniesSettled, issued.product)) } } /** * Generate a transaction performing close-out netting of two or more states. * - * @param signer the party who will sign the transaction. Must be one of the issuer or owner. + * @param signer the party who will sign the transaction. Must be one of the obligor or beneficiary. * @param states two or more states, which must be compatible for bilateral netting (same issuance definitions, * and same parties involved). */ @@ -570,7 +565,9 @@ class Obligation

: Contract { "signer is in the state parties" by (signer in netState!!.partyKeys) } - tx.addOutputState(states.reduce { stateA, stateB -> stateA.net(stateB) }) + val out = states.reduce { stateA, stateB -> stateA.net(stateB) } + if (out.quantity > 0L) + tx.addOutputState(out) tx.addCommand(Commands.Net(NetType.PAYMENT), signer) } @@ -578,20 +575,20 @@ class Obligation

: Contract { * Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey. */ fun generateIssue(tx: TransactionBuilder, - issuer: Party, + obligor: Party, issuanceDef: StateTemplate

, pennies: Long, - owner: PublicKey, + beneficiary: PublicKey, notary: Party) { check(tx.inputStates().isEmpty()) check(tx.outputStates().map { it.data }.sumObligationsOrNull

() == null) - val aggregateState = IssuanceDefinition(issuer, issuanceDef) - tx.addOutputState(State(Lifecycle.NORMAL, issuer, issuanceDef, pennies, owner), notary) - tx.addCommand(Commands.Issue(aggregateState), issuer.owningKey) + val aggregateState = IssuanceDefinition(obligor, issuanceDef) + tx.addOutputState(State(Lifecycle.NORMAL, obligor, issuanceDef, pennies, beneficiary), notary) + tx.addCommand(Commands.Issue(aggregateState), obligor.owningKey) } fun generatePaymentNetting(tx: TransactionBuilder, - currency: Issued

, + issued: Issued

, notary: Party, vararg states: State

) { requireThat { @@ -599,20 +596,20 @@ class Obligation

: Contract { } val groups = states.groupBy { it.multilateralNetState } val partyLookup = HashMap() - val signers = states.map { it.owner }.union(states.map { it.issuer.owningKey }).toSet() + val signers = states.map { it.beneficiary }.union(states.map { it.obligor.owningKey }).toSet() // Create a lookup table of the party that each public key represents. - states.map { it.issuer }.forEach { partyLookup.put(it.owningKey, it) } + states.map { it.obligor }.forEach { partyLookup.put(it.owningKey, it) } for ((netState, groupStates) in groups) { // Extract the net balances - val netBalances = netAmountsDue(extractAmountsDue(currency, states.asIterable())) + val netBalances = netAmountsDue(extractAmountsDue(issued.product, states.asIterable())) netBalances // Convert the balances into obligation state objects .map { entry -> State(Lifecycle.NORMAL, partyLookup[entry.key.first]!!, - netState.issuanceDef, entry.value.quantity, entry.key.second) + netState.template, entry.value.quantity, entry.key.second) } // Add the new states to the TX .forEach { tx.addOutputState(it, notary) } @@ -647,7 +644,7 @@ class Obligation

: Contract { val outState = stateAndRef.state.data.copy(lifecycle = lifecycle) tx.addInputState(stateAndRef) tx.addOutputState(outState, notary) - partiesUsed.add(stateAndRef.state.data.owner) + partiesUsed.add(stateAndRef.state.data.beneficiary) } tx.addCommand(Commands.SetLifecycle(aggregateState, lifecycle), partiesUsed.distinct()) } @@ -657,54 +654,55 @@ class Obligation

: Contract { /** * @param statesAndRefs a list of state objects, which MUST all have the same aggregate state. This is done as * only a single settlement command can be present in a transaction, to avoid potential problems with allocating - * cash to different obligation issuances. - * @param cashStatesAndRefs a list of cash state objects, which MUST all be in the same currency. It is strongly - * encouraged that these all have the same owner. + * assets to different obligation issuances. + * @param assetStatesAndRefs a list of fungible asset state objects, which MUST all be of the same issued product. + * It is strongly encouraged that these all have the same beneficiary. + * @param moveCommand the command used to move the asset state objects to their new owner. */ fun generateSettle(tx: TransactionBuilder, statesAndRefs: Iterable>>, - cashStatesAndRefs: Iterable>>, + assetStatesAndRefs: Iterable>>, + moveCommand: MoveCommand, notary: Party) { val states = statesAndRefs.map { it.state } - val notary = states.first().notary - val obligationIssuer = states.first().data.issuer - val obligationOwner = states.first().data.owner + val obligationIssuer = states.first().data.obligor + val obligationOwner = states.first().data.beneficiary requireThat { - "all cash states use the same notary" by (cashStatesAndRefs.all { it.state.notary == notary }) + "all fungible asset states use the same notary" by (assetStatesAndRefs.all { it.state.notary == notary }) "all obligation states are in the normal state" by (statesAndRefs.all { it.state.data.lifecycle == Lifecycle.NORMAL }) "all obligation states use the same notary" by (statesAndRefs.all { it.state.notary == notary }) - "all obligation states have the same issuer" by (statesAndRefs.all { it.state.data.issuer == obligationIssuer }) - "all obligation states have the same owner" by (statesAndRefs.all { it.state.data.owner == obligationOwner }) + "all obligation states have the same obligor" by (statesAndRefs.all { it.state.data.obligor == obligationIssuer }) + "all obligation states have the same beneficiary" by (statesAndRefs.all { it.state.data.beneficiary == obligationOwner }) } // TODO: A much better (but more complex) solution would be to have two iterators, one for obligations, - // one for cash, and step through each in a semi-synced manner. For now however we just bundle all the states + // one for the assets, and step through each in a semi-synced manner. For now however we just bundle all the states // on each side together val issuanceDef = getIssuanceDefinitionOrThrow(statesAndRefs.map { it.state.data }) val template = issuanceDef.template - val obligationTotal: Amount> = states.map { it.data }.sumObligations

() - var obligationRemaining: Amount> = obligationTotal - val cashSigners = HashSet() + val obligationTotal: Amount

= states.map { it.data }.sumObligations

() + var obligationRemaining: Amount

= obligationTotal + val assetSigners = HashSet() statesAndRefs.forEach { tx.addInputState(it) } - // Move the cash to the new owner - cashStatesAndRefs.forEach { + // Move the assets to the new beneficiary + assetStatesAndRefs.forEach { if (obligationRemaining.quantity > 0L) { - val cashState = it.state + val assetState = it.state tx.addInputState(it) - if (obligationRemaining >= cashState.data.amount) { - tx.addOutputState(cashState.data.move(cashState.data.amount, obligationOwner), notary) - obligationRemaining -= cashState.data.amount + if (obligationRemaining >= assetState.data.productAmount) { + tx.addOutputState(assetState.data.move(assetState.data.productAmount, obligationOwner), notary) + obligationRemaining -= assetState.data.productAmount } else { - // Split the state in two, sending the change back to the previous owner - tx.addOutputState(cashState.data.move(obligationRemaining, obligationOwner), notary) - tx.addOutputState(cashState.data.move(cashState.data.amount - obligationRemaining, cashState.data.owner), notary) + // Split the state in two, sending the change back to the previous beneficiary + tx.addOutputState(assetState.data.move(obligationRemaining, obligationOwner), notary) + tx.addOutputState(assetState.data.move(assetState.data.productAmount - obligationRemaining, assetState.data.owner), notary) obligationRemaining -= Amount(0L, obligationRemaining.token) } - cashSigners.add(cashState.data.owner) + assetSigners.add(assetState.data.owner) } } @@ -715,8 +713,8 @@ class Obligation

: Contract { // Destroy all of the states } - // Add the cash move command and obligation settle - tx.addCommand(Cash.Commands.Move(), cashSigners.toList()) + // Add the asset move command and obligation settle + tx.addCommand(moveCommand, assetSigners.toList()) tx.addCommand(Commands.Settle(issuanceDef, obligationTotal - obligationRemaining), obligationOwner) } @@ -731,17 +729,17 @@ class Obligation

: Contract { /** - * Convert a list of settlement states into total from each issuer to a owner. + * Convert a list of settlement states into total from each obligor to a beneficiary. * - * @return a map of issuer/owner pairs to the balance due. + * @return a map of obligor/beneficiary pairs to the balance due. */ -fun

extractAmountsDue(currency: Issued

, states: Iterable>): Map, Amount>> { - val balances = HashMap, Amount>>() +fun

extractAmountsDue(product: P, states: Iterable>): Map, Amount

> { + val balances = HashMap, Amount

>() states.forEach { state -> - val key = Pair(state.issuer.owningKey, state.owner) - val balance = balances[key] ?: Amount(0L, currency) - balances[key] = balance + state.amount + val key = Pair(state.obligor.owningKey, state.beneficiary) + val balance = balances[key] ?: Amount(0L, product) + balances[key] = balance + state.productAmount } return balances @@ -750,12 +748,12 @@ fun

extractAmountsDue(currency: Issued

, states: Iterable netAmountsDue(balances: Map, Amount>>): Map, Amount>> { - val nettedBalances = HashMap, Amount>>() +fun

netAmountsDue(balances: Map, Amount

>): Map, Amount

> { + val nettedBalances = HashMap, Amount

>() balances.forEach { balance -> - val (issuer, owner) = balance.key - val oppositeKey = Pair(owner, issuer) + val (obligor, beneficiary) = balance.key + val oppositeKey = Pair(beneficiary, obligor) val opposite = (balances[oppositeKey] ?: Amount(0L, balance.value.token)) // Drop zero balances if (balance.value > opposite) { @@ -770,9 +768,9 @@ fun

netAmountsDue(balances: Map, Amount /** * Calculate the total balance movement for each party in the transaction, based off a summary of balances between - * each issuer and owner. + * each obligor and beneficiary. * - * @param balances payments due, indexed by issuer and owner. Zero balances are stripped from the map before being + * @param balances payments due, indexed by obligor and beneficiary. Zero balances are stripped from the map before being * returned. */ fun

sumAmountsDue(balances: Map, Amount

>): Map { @@ -785,17 +783,17 @@ fun

sumAmountsDue(balances: Map, Amount

>): Map } for ((key, amount) in balances) { - val (issuer, owner) = key - // Subtract it from the issuer - sum[issuer] = sum[issuer]!! - amount.quantity - // Add it to the owner - sum[owner] = sum[owner]!! + amount.quantity + val (obligor, beneficiary) = key + // Subtract it from the obligor + sum[obligor] = sum[obligor]!! - amount.quantity + // Add it to the beneficiary + sum[beneficiary] = sum[beneficiary]!! + amount.quantity } // Strip zero balances val iterator = sum.iterator() while (iterator.hasNext()) { - val (key, amount) = iterator.next() + val amount = iterator.next().value if (amount == 0L) { iterator.remove() } @@ -804,16 +802,15 @@ fun

sumAmountsDue(balances: Map, Amount

>): Map return sum } -/** Sums the cash states in the list, throwing an exception if there are none. - * All cash states in the list are presumed to be nettable. - */ -fun

Iterable.sumObligations() = filterIsInstance>().map { it.amount }.sumOrThrow() +/** Sums the obligation states in the list, throwing an exception if there are none. All state objects in the list are presumed to be nettable. */ +fun

Iterable.sumObligations(): Amount

+ = filterIsInstance>().map { it.amount }.sumOrThrow() -/** Sums the cash settlement states in the list, returning null if there are none. */ -fun

Iterable.sumObligationsOrNull() +/** Sums the obligation states in the list, returning null if there are none. */ +fun

Iterable.sumObligationsOrNull(): Amount

? = filterIsInstance>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrNull() -/** Sums the cash settlement states in the list, returning zero of the given currency if there are none. */ -fun

Iterable.sumObligationsOrZero(currency: Issued

) - = filterIsInstance>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(currency) +/** Sums the obligation states in the list, returning zero of the given product if there are none. */ +fun

Iterable.sumObligationsOrZero(product: P): Amount

+ = filterIsInstance>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(product) diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/testing/TestUtils.kt b/contracts/src/main/kotlin/com/r3corda/contracts/testing/TestUtils.kt index d7f3dfc526..bd13e1178e 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/testing/TestUtils.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/testing/TestUtils.kt @@ -1,20 +1,26 @@ package com.r3corda.contracts.testing import com.r3corda.contracts.* -import com.r3corda.contracts.cash.CASH_PROGRAM_ID -import com.r3corda.contracts.cash.Cash +import com.r3corda.contracts.asset.CASH_PROGRAM_ID +import com.r3corda.contracts.asset.Cash +import com.r3corda.contracts.asset.Obligation import com.r3corda.core.contracts.Amount import com.r3corda.core.contracts.Contract +import com.r3corda.core.contracts.ContractState import com.r3corda.core.contracts.DUMMY_PROGRAM_ID import com.r3corda.core.contracts.DummyContract +import com.r3corda.core.contracts.DummyState import com.r3corda.core.contracts.PartyAndReference import com.r3corda.core.contracts.Issued -import com.r3corda.core.contracts.ContractState import com.r3corda.core.contracts.TransactionState import com.r3corda.core.crypto.NullPublicKey import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.generateKeyPair +import com.r3corda.core.testing.MINI_CORP +import com.r3corda.core.testing.TEST_TX_TIME +import com.r3corda.core.utilities.nonEmptySetOf import java.security.PublicKey +import java.time.Instant import java.util.* // In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside @@ -27,7 +33,7 @@ val TEST_PROGRAM_MAP: Map> = mapOf( IRS_PROGRAM_ID to InterestRateSwap::class.java ) -fun generateState() = DummyContract.State(Random().nextInt()) +fun generateState() = DummyState(Random().nextInt()) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // @@ -56,6 +62,12 @@ object JavaTestHelpers { @JvmStatic fun withNotary(state: Cash.State, notary: Party) = TransactionState(state, notary) @JvmStatic fun withDeposit(state: Cash.State, deposit: PartyAndReference) = state.copy(amount = state.amount.copy(token = state.amount.token.copy(issuer = deposit))) + @JvmStatic fun at(state: Obligation.State, dueBefore: Instant) = state.copy(template = state.template.copy(dueBefore = dueBefore)) + @JvmStatic fun at(issuanceDef: Obligation.IssuanceDefinition, dueBefore: Instant) = issuanceDef.copy(template = issuanceDef.template.copy(dueBefore = dueBefore)) + @JvmStatic fun between(state: Obligation.State, parties: Pair) = state.copy(obligor = parties.first, beneficiary = parties.second) + @JvmStatic fun ownedBy(state: Obligation.State, owner: PublicKey) = state.copy(beneficiary = owner) + @JvmStatic fun issuedBy(state: Obligation.State, party: Party) = state.copy(obligor = party) + @JvmStatic fun ownedBy(state: CommercialPaper.State, owner: PublicKey) = state.copy(owner = owner) @JvmStatic fun withNotary(state: CommercialPaper.State, notary: Party) = TransactionState(state, notary) @JvmStatic fun ownedBy(state: ICommercialPaperState, new_owner: PublicKey) = state.withOwner(new_owner) @@ -66,6 +78,12 @@ object JavaTestHelpers { Amount>(amount.quantity, Issued(DUMMY_CASH_ISSUER, amount.token)), NullPublicKey) @JvmStatic fun STATE(amount: Amount>) = Cash.State(amount, NullPublicKey) + + // Allows you to write 100.DOLLARS.OBLIGATION + @JvmStatic fun OBLIGATION_DEF(issued: Issued) + = Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(issued), TEST_TX_TIME) + @JvmStatic fun OBLIGATION(amount: Amount>) = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP, + OBLIGATION_DEF(amount.token), amount.quantity, NullPublicKey) } @@ -75,6 +93,12 @@ infix fun Cash.State.`issued by`(deposit: PartyAndReference) = JavaTestHelpers.i infix fun Cash.State.`with notary`(notary: Party) = JavaTestHelpers.withNotary(this, notary) infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = JavaTestHelpers.withDeposit(this, deposit) +infix fun Obligation.State.`at`(dueBefore: Instant) = JavaTestHelpers.at(this, dueBefore) +infix fun Obligation.IssuanceDefinition.`at`(dueBefore: Instant) = JavaTestHelpers.at(this, dueBefore) +infix fun Obligation.State.`between`(parties: Pair) = JavaTestHelpers.between(this, parties) +infix fun Obligation.State.`owned by`(owner: PublicKey) = JavaTestHelpers.ownedBy(this, owner) +infix fun Obligation.State.`issued by`(party: Party) = JavaTestHelpers.issuedBy(this, party) + infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = JavaTestHelpers.ownedBy(this, owner) infix fun CommercialPaper.State.`with notary`(notary: Party) = JavaTestHelpers.withNotary(this, notary) infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = JavaTestHelpers.ownedBy(this, new_owner) @@ -87,3 +111,6 @@ val DUMMY_CASH_ISSUER = Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public). val Amount.CASH: Cash.State get() = JavaTestHelpers.CASH(this) val Amount>.STATE: Cash.State get() = JavaTestHelpers.STATE(this) +/** Allows you to write 100.DOLLARS.CASH */ +val Issued.OBLIGATION_DEF: Obligation.StateTemplate get() = JavaTestHelpers.OBLIGATION_DEF(this) +val Amount>.OBLIGATION: Obligation.State get() = JavaTestHelpers.OBLIGATION(this) diff --git a/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt b/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt index ec7bec2404..456b8dd391 100644 --- a/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt +++ b/contracts/src/main/kotlin/com/r3corda/contracts/testing/WalletFiller.kt @@ -1,7 +1,7 @@ @file:JvmName("WalletFiller") package com.r3corda.contracts.testing -import com.r3corda.contracts.cash.Cash +import com.r3corda.contracts.asset.Cash import com.r3corda.core.contracts.Amount import com.r3corda.core.contracts.Issued import com.r3corda.core.contracts.SignedTransaction @@ -66,6 +66,7 @@ private fun calculateRandomlySizedAmounts(howMuch: Amount, min: Int, m val numStates = min + Math.floor(rng.nextDouble() * (max - min)).toInt() val amounts = LongArray(numStates) val baseSize = howMuch.quantity / numStates + check(baseSize > 0) { baseSize } var filledSoFar = 0L for (i in 0..numStates - 1) { if (i < numStates - 1) { @@ -76,6 +77,7 @@ private fun calculateRandomlySizedAmounts(howMuch: Amount, min: Int, m // Handle inexact rounding. amounts[i] = howMuch.quantity - filledSoFar } + check(amounts[i] >= 0) { amounts[i] } } check(amounts.sum() == howMuch.quantity) return amounts diff --git a/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt b/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt index 514f230675..7efd145934 100644 --- a/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt +++ b/contracts/src/main/kotlin/com/r3corda/protocols/TwoPartyTradeProtocol.kt @@ -1,13 +1,12 @@ package com.r3corda.protocols import co.paralleluniverse.fibers.Suspendable -import com.r3corda.contracts.cash.Cash -import com.r3corda.contracts.cash.sumCashBy +import com.r3corda.contracts.asset.Cash +import com.r3corda.contracts.asset.sumCashBy import com.r3corda.core.contracts.* import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.signWithECDSA -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.NodeInfo import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.random63BitValue @@ -43,7 +42,8 @@ import java.util.* * To see an example of how to use this class, look at the unit tests. */ object TwoPartyTradeProtocol { - val TRADE_TOPIC = "platform.trade" + + val TOPIC = "platform.trade" class UnacceptablePriceException(val givenPrice: Amount>) : Exception() class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() { @@ -61,7 +61,7 @@ object TwoPartyTradeProtocol { class SignaturesFromSeller(val sellerSig: DigitalSignature.WithKey, val notarySig: DigitalSignature.LegallyIdentifiable) - open class Seller(val otherSide: SingleMessageRecipient, + open class Seller(val otherSide: Party, val notaryNode: NodeInfo, val assetToSell: StateAndRef, val price: Amount>, @@ -83,6 +83,8 @@ object TwoPartyTradeProtocol { fun tracker() = ProgressTracker(AWAITING_PROPOSAL, VERIFYING, SIGNING, NOTARY, SENDING_SIGS) } + override val topic: String get() = TOPIC + @Suspendable override fun call(): SignedTransaction { val partialTX: SignedTransaction = receiveAndCheckProposedTransaction() @@ -109,7 +111,7 @@ object TwoPartyTradeProtocol { // Make the first message we'll send to kick off the protocol. val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID) - val maybeSTX = sendAndReceive(TRADE_TOPIC, otherSide, buyerSessionID, sessionID, hello) + val maybeSTX = sendAndReceive(otherSide, buyerSessionID, sessionID, hello) progressTracker.currentStep = VERIFYING @@ -167,12 +169,12 @@ object TwoPartyTradeProtocol { logger.trace { "Built finished transaction, sending back to secondary!" } - send(TRADE_TOPIC, otherSide, buyerSessionID, SignaturesFromSeller(ourSignature, notarySignature)) + send(otherSide, buyerSessionID, SignaturesFromSeller(ourSignature, notarySignature)) return fullySigned } } - open class Buyer(val otherSide: SingleMessageRecipient, + open class Buyer(val otherSide: Party, val notary: Party, val acceptablePrice: Amount>, val typeToBuy: Class, @@ -186,6 +188,7 @@ object TwoPartyTradeProtocol { object SWAPPING_SIGNATURES : ProgressTracker.Step("Swapping signatures with the seller") + override val topic: String get() = TOPIC override val progressTracker = ProgressTracker(RECEIVING, VERIFYING, SIGNING, SWAPPING_SIGNATURES) @Suspendable @@ -196,8 +199,6 @@ object TwoPartyTradeProtocol { val (ptx, cashSigningPubKeys) = assembleSharedTX(tradeRequest) val stx = signWithOurKeys(cashSigningPubKeys, ptx) - // exitProcess(0) - val signatures = swapSignaturesWithSeller(stx, tradeRequest.sessionID) logger.trace { "Got signatures from seller, verifying ... " } @@ -216,7 +217,7 @@ object TwoPartyTradeProtocol { private fun receiveAndValidateTradeRequest(): SellerTradeInfo { progressTracker.currentStep = RECEIVING // Wait for a trade request to come in on our pre-provided session ID. - val maybeTradeRequest = receive(TRADE_TOPIC, sessionID) + val maybeTradeRequest = receive(sessionID) progressTracker.currentStep = VERIFYING maybeTradeRequest.validate { @@ -247,7 +248,7 @@ object TwoPartyTradeProtocol { // TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx. - return sendAndReceive(TRADE_TOPIC, otherSide, theirSessionID, sessionID, stx).validate { it } + return sendAndReceive(otherSide, theirSessionID, sessionID, stx).validate { it } } private fun signWithOurKeys(cashSigningPubKeys: List, ptx: TransactionBuilder): SignedTransaction { diff --git a/contracts/src/test/java/com/r3corda/contracts/asset/CashTestsJava.java b/contracts/src/test/java/com/r3corda/contracts/asset/CashTestsJava.java new file mode 100644 index 0000000000..36fced1951 --- /dev/null +++ b/contracts/src/test/java/com/r3corda/contracts/asset/CashTestsJava.java @@ -0,0 +1,61 @@ +package com.r3corda.contracts.asset; + +import com.r3corda.core.contracts.PartyAndReference; +import com.r3corda.core.serialization.OpaqueBytes; +import kotlin.Unit; +import org.junit.Test; + +import static com.r3corda.core.testing.JavaTestHelpers.*; +import static com.r3corda.core.contracts.JavaTestHelpers.*; +import static com.r3corda.contracts.testing.JavaTestHelpers.*; + +/** + * This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL + */ +public class CashTestsJava { + + private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});; + private PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef); + private Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), getDUMMY_PUBKEY_1()); + private Cash.State outState = new Cash.State(inState.getAmount(), getDUMMY_PUBKEY_2()); + + @Test + public void trivial() { + ledger(lg -> { + lg.transaction(tx -> { + tx.input(inState); + tx.failsWith("the amounts balance"); + + tx.tweak(tw -> { + tw.output(new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), getDUMMY_PUBKEY_2())); + return tw.failsWith("the amounts balance"); + }); + + tx.tweak(tw -> { + tw.output(outState); + // No command arguments + return tw.failsWith("required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command"); + }); + tx.tweak(tw -> { + tw.output(outState); + tw.command(getDUMMY_PUBKEY_2(), new Cash.Commands.Move()); + return tw.failsWith("the owning keys are the same as the signing keys"); + }); + tx.tweak(tw -> { + tw.output(outState); + tw.output(issuedBy(outState, getMINI_CORP())); + tw.command(getDUMMY_PUBKEY_1(), new Cash.Commands.Move()); + return tw.failsWith("at least one asset input"); + }); + + // Simple reallocation works. + return tx.tweak(tw -> { + tw.output(outState); + tw.command(getDUMMY_PUBKEY_1(), new Cash.Commands.Move()); + return tw.verifies(); + }); + }); + return Unit.INSTANCE; + }); + } +} diff --git a/contracts/src/test/java/com/r3corda/contracts/cash/CashTestsJava.java b/contracts/src/test/java/com/r3corda/contracts/cash/CashTestsJava.java deleted file mode 100644 index 63772ab0dc..0000000000 --- a/contracts/src/test/java/com/r3corda/contracts/cash/CashTestsJava.java +++ /dev/null @@ -1,58 +0,0 @@ -package com.r3corda.contracts.cash; - -import com.r3corda.core.contracts.PartyAndReference; -import com.r3corda.core.serialization.OpaqueBytes; -import org.junit.Test; - -import static com.r3corda.core.testing.JavaTestHelpers.*; -import static com.r3corda.core.contracts.JavaTestHelpers.*; -import static com.r3corda.contracts.testing.JavaTestHelpers.*; - -/** - * This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL - */ -public class CashTestsJava { - - private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});; - private PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef); - private Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), getDUMMY_PUBKEY_1()); - private Cash.State outState = new Cash.State(inState.getAmount(), getDUMMY_PUBKEY_2()); - - @Test - public void trivial() { - - transaction(tx -> { - tx.input(inState); - tx.failsRequirement("the amounts balance"); - - tx.tweak(tw -> { - tw.output(new Cash.State(issuedBy(DOLLARS(2000), defaultIssuer), getDUMMY_PUBKEY_2())); - return tw.failsRequirement("the amounts balance"); - }); - - tx.tweak(tw -> { - tw.output(outState); - // No command arguments - return tw.failsRequirement("required com.r3corda.contracts.cash.FungibleAsset.Commands.Move command"); - }); - tx.tweak(tw -> { - tw.output(outState); - tw.arg(getDUMMY_PUBKEY_2(), new Cash.Commands.Move()); - return tw.failsRequirement("the owning keys are the same as the signing keys"); - }); - tx.tweak(tw -> { - tw.output(outState); - tw.output(issuedBy(outState, getMINI_CORP())); - tw.arg(getDUMMY_PUBKEY_1(), new Cash.Commands.Move()); - return tw.failsRequirement("at least one asset input"); - }); - - // Simple reallocation works. - return tx.tweak(tw -> { - tw.output(outState); - tw.arg(getDUMMY_PUBKEY_1(), new Cash.Commands.Move()); - return tw.accepts(); - }); - }); - } -} diff --git a/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt b/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt index 9b69908e1e..0f56e5f8d2 100644 --- a/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt +++ b/contracts/src/test/kotlin/com/r3corda/contracts/CommercialPaperTests.kt @@ -1,6 +1,6 @@ package com.r3corda.contracts -import com.r3corda.contracts.cash.Cash +import com.r3corda.contracts.asset.Cash import com.r3corda.contracts.testing.* import com.r3corda.core.contracts.* import com.r3corda.core.crypto.SecureHash @@ -12,15 +12,15 @@ import org.junit.Test import org.junit.runner.RunWith import org.junit.runners.Parameterized import java.time.Instant -import java.util.Currency +import java.util.* import kotlin.test.assertFailsWith import kotlin.test.assertTrue interface ICommercialPaperTestTemplate { - open fun getPaper(): ICommercialPaperState - open fun getIssueCommand(): CommandData - open fun getRedeemCommand(): CommandData - open fun getMoveCommand(): CommandData + fun getPaper(): ICommercialPaperState + fun getIssueCommand(): CommandData + fun getRedeemCommand(): CommandData + fun getMoveCommand(): CommandData } class JavaCommercialPaperTest() : ICommercialPaperTestTemplate { @@ -63,81 +63,113 @@ class CommercialPaperTestsGeneric { val issuer = MEGA_CORP.ref(123) @Test - fun ok() { - trade().verify() - } + fun `trade lifecycle test`() { + val someProfits = 1200.DOLLARS `issued by` issuer + ledger { + unverifiedTransaction { + output("alice's $900", 900.DOLLARS.CASH `issued by` issuer `owned by` ALICE_PUBKEY) + output("some profits", someProfits.STATE `owned by` MEGA_CORP_PUBKEY) + } - @Test - fun `not matured at redemption`() { - trade(redemptionTime = TEST_TX_TIME + 2.days).expectFailureOfTx(3, "must have matured") + // Some CP is issued onto the ledger by MegaCorp. + transaction("Issuance") { + output("paper") { thisTest.getPaper() } + command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } + timestamp(TEST_TX_TIME) + this.verifies() + } + + // The CP is sold to alice for her $900, $100 less than the face value. At 10% interest after only 7 days, + // that sounds a bit too good to be true! + transaction("Trade") { + input("paper") + input("alice's $900") + output("borrowed $900") { 900.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } + output("alice's paper") { "paper".output().data `owned by` ALICE_PUBKEY } + command(ALICE_PUBKEY) { Cash.Commands.Move() } + command(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() } + this.verifies() + } + + // Time passes, and Alice redeem's her CP for $1000, netting a $100 profit. MegaCorp has received $1200 + // as a single payment from somewhere and uses it to pay Alice off, keeping the remaining $200 as change. + transaction("Redemption") { + input("alice's paper") + input("some profits") + + fun TransactionDSL>.outputs(aliceGetsBack: Amount>) { + output("Alice's profit") { aliceGetsBack.STATE `owned by` ALICE_PUBKEY } + output("Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP_PUBKEY } + } + + command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + command(ALICE_PUBKEY) { thisTest.getRedeemCommand() } + + tweak { + outputs(700.DOLLARS `issued by` issuer) + timestamp(TEST_TX_TIME + 8.days) + this `fails with` "received amount equals the face value" + } + outputs(1000.DOLLARS `issued by` issuer) + + + tweak { + timestamp(TEST_TX_TIME + 2.days) + this `fails with` "must have matured" + } + timestamp(TEST_TX_TIME + 8.days) + + tweak { + output { "paper".output().data } + this `fails with` "must be destroyed" + } + + this.verifies() + } + } } @Test fun `key mismatch at issue`() { - transactionGroup { - transaction { - output { thisTest.getPaper() } - arg(DUMMY_PUBKEY_1) { thisTest.getIssueCommand() } - timestamp(TEST_TX_TIME) - } - - expectFailureOfTx(1, "signed by the claimed issuer") + transaction { + output { thisTest.getPaper() } + command(DUMMY_PUBKEY_1) { thisTest.getIssueCommand() } + timestamp(TEST_TX_TIME) + this `fails with` "signed by the claimed issuer" } } @Test fun `face value is not zero`() { - transactionGroup { - transaction { - output { thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer) } - arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } - timestamp(TEST_TX_TIME) - } - - expectFailureOfTx(1, "face value is not zero") + transaction { + output { thisTest.getPaper().withFaceValue(0.DOLLARS `issued by` issuer) } + command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } + timestamp(TEST_TX_TIME) + this `fails with` "face value is not zero" } } @Test fun `maturity date not in the past`() { - transactionGroup { - transaction { - output { thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days) } - arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } - timestamp(TEST_TX_TIME) - } - - expectFailureOfTx(1, "maturity date is not in the past") + transaction { + output { thisTest.getPaper().withMaturityDate(TEST_TX_TIME - 10.days) } + command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } + timestamp(TEST_TX_TIME) + this `fails with` "maturity date is not in the past" } } @Test fun `issue cannot replace an existing state`() { - transactionGroup { - roots { - transaction(thisTest.getPaper() `with notary` DUMMY_NOTARY label "paper") - } - transaction { - input("paper") - output { thisTest.getPaper() } - arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } - timestamp(TEST_TX_TIME) - } - - expectFailureOfTx(1, "there is no input state") + transaction { + input(thisTest.getPaper()) + output { thisTest.getPaper() } + command(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } + timestamp(TEST_TX_TIME) + this `fails with` "there is no input state" } } - @Test - fun `did not receive enough money at redemption`() { - trade(aliceGetsBack = 700.DOLLARS `issued by` issuer).expectFailureOfTx(3, "received amount equals the face value") - } - - @Test - fun `paper must be destroyed by redemption`() { - trade(destroyPaperAtRedemption = false).expectFailureOfTx(3, "must be destroyed") - } - fun cashOutputsToWallet(vararg outputs: TransactionState): Pair>> { val ltx = LedgerTransaction(emptyList(), listOf(*outputs), emptyList(), emptyList(), SecureHash.randomSHA256(), emptyList(), TransactionType.General()) return Pair(ltx, outputs.mapIndexed { index, state -> StateAndRef(state, StateRef(ltx.id, index)) }) @@ -199,52 +231,4 @@ class CommercialPaperTestsGeneric { TransactionGroup(setOf(issueTX, moveTX, validRedemption), setOf(corpWalletTX, alicesWalletTX)).verify() } - - // Generate a trade lifecycle with various parameters. - fun trade(redemptionTime: Instant = TEST_TX_TIME + 8.days, - aliceGetsBack: Amount> = 1000.DOLLARS `issued by` issuer, - destroyPaperAtRedemption: Boolean = true): TransactionGroupDSL { - val someProfits = 1200.DOLLARS `issued by` issuer - return transactionGroupFor() { - roots { - transaction(900.DOLLARS.CASH `issued by` issuer `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY label "alice's $900") - transaction(someProfits.STATE `owned by` MEGA_CORP_PUBKEY `with notary` DUMMY_NOTARY label "some profits") - } - - // Some CP is issued onto the ledger by MegaCorp. - transaction("Issuance") { - output("paper") { thisTest.getPaper() } - arg(MEGA_CORP_PUBKEY) { thisTest.getIssueCommand() } - timestamp(TEST_TX_TIME) - } - - // The CP is sold to alice for her $900, $100 less than the face value. At 10% interest after only 7 days, - // that sounds a bit too good to be true! - transaction("Trade") { - input("paper") - input("alice's $900") - output("borrowed $900") { 900.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } - output("alice's paper") { "paper".output.data `owned by` ALICE_PUBKEY } - arg(ALICE_PUBKEY) { Cash.Commands.Move() } - arg(MEGA_CORP_PUBKEY) { thisTest.getMoveCommand() } - } - - // Time passes, and Alice redeem's her CP for $1000, netting a $100 profit. MegaCorp has received $1200 - // as a single payment from somewhere and uses it to pay Alice off, keeping the remaining $200 as change. - transaction("Redemption") { - input("alice's paper") - input("some profits") - - output("Alice's profit") { aliceGetsBack.STATE `owned by` ALICE_PUBKEY } - output("Change") { (someProfits - aliceGetsBack).STATE `owned by` MEGA_CORP_PUBKEY } - if (!destroyPaperAtRedemption) - output { "paper".output.data } - - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } - arg(ALICE_PUBKEY) { thisTest.getRedeemCommand() } - - timestamp(redemptionTime) - } - } - } } diff --git a/contracts/src/test/kotlin/com/r3corda/contracts/IRSTests.kt b/contracts/src/test/kotlin/com/r3corda/contracts/IRSTests.kt index 6075cff0ed..e771e25140 100644 --- a/contracts/src/test/kotlin/com/r3corda/contracts/IRSTests.kt +++ b/contracts/src/test/kotlin/com/r3corda/contracts/IRSTests.kt @@ -200,12 +200,12 @@ class IRSTests { @Test fun ok() { - trade().verify() + trade().verifies() } @Test fun `ok with groups`() { - tradegroups().verify() + tradegroups().verifies() } /** @@ -360,38 +360,40 @@ class IRSTests { /** * Generates a typical transactional history for an IRS. */ - fun trade(): TransactionGroupDSL { + fun trade(): LedgerDSL { val ld = LocalDate.of(2016, 3, 8) val bd = BigDecimal("0.0063518") - val txgroup: TransactionGroupDSL = transactionGroupFor() { + return ledger { transaction("Agreement") { output("irs post agreement") { singleIRS() } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) + this.verifies() } transaction("Fix") { input("irs post agreement") + val postAgreement = "irs post agreement".output() output("irs post first fixing") { - "irs post agreement".output.data.copy( - "irs post agreement".output.data.fixedLeg, - "irs post agreement".output.data.floatingLeg, - "irs post agreement".output.data.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))), - "irs post agreement".output.data.common + postAgreement.data.copy( + postAgreement.data.fixedLeg, + postAgreement.data.floatingLeg, + postAgreement.data.calculation.applyFixing(ld, FixedRate(RatioUnit(bd))), + postAgreement.data.common ) } - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } timestamp(TEST_TX_TIME) + this.verifies() } } - return txgroup } @Test @@ -399,9 +401,9 @@ class IRSTests { transaction { input() { singleIRS() } output("irs post agreement") { singleIRS() } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "There are no in states for an agreement" + this `fails with` "There are no in states for an agreement" } } @@ -413,9 +415,9 @@ class IRSTests { output() { irs.copy(calculation = irs.calculation.copy(fixedLegPaymentSchedule = emptySchedule)) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "There are events in the fix schedule" + this `fails with` "There are events in the fix schedule" } } @@ -427,9 +429,9 @@ class IRSTests { output() { irs.copy(calculation = irs.calculation.copy(floatingLegPaymentSchedule = emptySchedule)) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "There are events in the float schedule" + this `fails with` "There are events in the float schedule" } } @@ -440,18 +442,18 @@ class IRSTests { output() { irs.copy(irs.fixedLeg.copy(notional = irs.fixedLeg.notional.copy(quantity = 0))) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "All notionals must be non zero" + this `fails with` "All notionals must be non zero" } transaction { output() { irs.copy(irs.fixedLeg.copy(notional = irs.floatingLeg.notional.copy(quantity = 0))) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "All notionals must be non zero" + this `fails with` "All notionals must be non zero" } } @@ -463,9 +465,9 @@ class IRSTests { output() { modifiedIRS } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The fixed leg rate must be positive" + this `fails with` "The fixed leg rate must be positive" } } @@ -480,9 +482,9 @@ class IRSTests { output() { modifiedIRS } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The currency of the notionals must be the same" + this `fails with` "The currency of the notionals must be the same" } } @@ -494,9 +496,9 @@ class IRSTests { output() { modifiedIRS } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "All leg notionals must be the same" + this `fails with` "All leg notionals must be the same" } } @@ -508,9 +510,9 @@ class IRSTests { output() { modifiedIRS1 } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The effective date is before the termination date for the fixed leg" + this `fails with` "The effective date is before the termination date for the fixed leg" } val modifiedIRS2 = irs.copy(floatingLeg = irs.floatingLeg.copy(terminationDate = irs.floatingLeg.effectiveDate.minusDays(1))) @@ -518,9 +520,9 @@ class IRSTests { output() { modifiedIRS2 } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The effective date is before the termination date for the floating leg" + this `fails with` "The effective date is before the termination date for the floating leg" } } @@ -533,9 +535,9 @@ class IRSTests { output() { modifiedIRS3 } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The termination dates are aligned" + this `fails with` "The termination dates are aligned" } @@ -544,24 +546,23 @@ class IRSTests { output() { modifiedIRS4 } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this `fails requirement` "The effective dates are aligned" + this `fails with` "The effective dates are aligned" } } @Test fun `various fixing tests`() { - val ld = LocalDate.of(2016, 3, 8) val bd = BigDecimal("0.0063518") transaction { output("irs post agreement") { singleIRS() } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) - this.accepts() + this.verifies() } val oldIRS = singleIRS(1) @@ -578,31 +579,31 @@ class IRSTests { // Templated tweak for reference. A corrent fixing applied should be ok tweak { - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } timestamp(TEST_TX_TIME) - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } output() { newIRS } - this.accepts() + this.verifies() } // This test makes sure that verify confirms the fixing was applied and there is a difference in the old and new tweak { - arg(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } timestamp(TEST_TX_TIME) - arg(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } output() { oldIRS } - this`fails requirement` "There is at least one difference in the IRS floating leg payment schedules" + this `fails with` "There is at least one difference in the IRS floating leg payment schedules" } // This tests tries to sneak in a change to another fixing (which may or may not be the latest one) tweak { - arg(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } timestamp(TEST_TX_TIME) - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } @@ -619,14 +620,14 @@ class IRSTests { newIRS.common ) } - this`fails requirement` "There is only one change in the IRS floating leg payment schedule" + this `fails with` "There is only one change in the IRS floating leg payment schedule" } // This tests modifies the payment currency for the fixing tweak { - arg(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } timestamp(TEST_TX_TIME) - arg(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld, Tenor("3M")), bd) } val latestReset = newIRS.calculation.floatingLegPaymentSchedule.filter { it.value.rate is FixedRate }.maxBy { it.key } val modifiedLatestResetValue = latestReset!!.value.copy(notional = Amount(latestReset.value.notional.quantity, Currency.getInstance("JPY"))) @@ -640,7 +641,7 @@ class IRSTests { newIRS.common ) } - this`fails requirement` "The fix payment has the same currency as the notional" + this `fails with` "The fix payment has the same currency as the notional" } } } @@ -652,13 +653,13 @@ class IRSTests { * result and the grouping won't work either. * In reality, the only fields that should be in common will be the next fixing date and the reference rate. */ - fun tradegroups(): TransactionGroupDSL { + fun tradegroups(): LedgerDSL { val ld1 = LocalDate.of(2016, 3, 8) val bd1 = BigDecimal("0.0063518") val irs = singleIRS() - val txgroup: TransactionGroupDSL = transactionGroupFor() { + return ledger { transaction("Agreement") { output("irs post agreement1") { irs.copy( @@ -668,8 +669,9 @@ class IRSTests { irs.common.copy(tradeID = "t1") ) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) + this.verifies() } transaction("Agreement") { @@ -681,40 +683,43 @@ class IRSTests { irs.common.copy(tradeID = "t2") ) } - arg(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } + command(MEGA_CORP_PUBKEY) { InterestRateSwap.Commands.Agree() } timestamp(TEST_TX_TIME) + this.verifies() } transaction("Fix") { input("irs post agreement1") input("irs post agreement2") + val postAgreement1 = "irs post agreement1".output() output("irs post first fixing1") { - "irs post agreement1".output.data.copy( - "irs post agreement1".output.data.fixedLeg, - "irs post agreement1".output.data.floatingLeg, - "irs post agreement1".output.data.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))), - "irs post agreement1".output.data.common.copy(tradeID = "t1") + postAgreement1.data.copy( + postAgreement1.data.fixedLeg, + postAgreement1.data.floatingLeg, + postAgreement1.data.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))), + postAgreement1.data.common.copy(tradeID = "t1") ) } + val postAgreement2 = "irs post agreement2".output() output("irs post first fixing2") { - "irs post agreement2".output.data.copy( - "irs post agreement2".output.data.fixedLeg, - "irs post agreement2".output.data.floatingLeg, - "irs post agreement2".output.data.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))), - "irs post agreement2".output.data.common.copy(tradeID = "t2") + postAgreement2.data.copy( + postAgreement2.data.fixedLeg, + postAgreement2.data.floatingLeg, + postAgreement2.data.calculation.applyFixing(ld1, FixedRate(RatioUnit(bd1))), + postAgreement2.data.common.copy(tradeID = "t2") ) } - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { InterestRateSwap.Commands.Fix() } - arg(ORACLE_PUBKEY) { + command(ORACLE_PUBKEY) { Fix(FixOf("ICE LIBOR", ld1, Tenor("3M")), bd1) } timestamp(TEST_TX_TIME) + this.verifies() } } - return txgroup } } diff --git a/contracts/src/test/kotlin/com/r3corda/contracts/cash/CashTests.kt b/contracts/src/test/kotlin/com/r3corda/contracts/asset/CashTests.kt similarity index 80% rename from contracts/src/test/kotlin/com/r3corda/contracts/cash/CashTests.kt rename to contracts/src/test/kotlin/com/r3corda/contracts/asset/CashTests.kt index 0b0e355720..a4adf2afbb 100644 --- a/contracts/src/test/kotlin/com/r3corda/contracts/cash/CashTests.kt +++ b/contracts/src/test/kotlin/com/r3corda/contracts/asset/CashTests.kt @@ -1,4 +1,4 @@ -package com.r3corda.contracts.cash +package com.r3corda.contracts.asset import com.r3corda.contracts.testing.`issued by` import com.r3corda.contracts.testing.`owned by` @@ -31,33 +31,33 @@ class CashTests { fun trivial() { transaction { input { inState } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" tweak { output { outState.copy(amount = 2000.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } tweak { output { outState } // No command arguments - this `fails requirement` "required com.r3corda.contracts.cash.FungibleAsset.Commands.Move command" + this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command" } tweak { output { outState } - arg(DUMMY_PUBKEY_2) { Cash.Commands.Move() } - this `fails requirement` "the owning keys are the same as the signing keys" + command(DUMMY_PUBKEY_2) { Cash.Commands.Move() } + this `fails with` "the owning keys are the same as the signing keys" } tweak { output { outState } output { outState `issued by` MINI_CORP } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this `fails requirement` "at least one asset input" + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this `fails with` "at least one asset input" } // Simple reallocation works. tweak { output { outState } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this.accepts() + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this.verifies() } } } @@ -66,19 +66,19 @@ class CashTests { fun issueMoney() { // Check we can't "move" money into existence. transaction { - input { DummyContract.State() } + input { DummyState() } output { outState } - arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() } + command(MINI_CORP_PUBKEY) { Cash.Commands.Move() } - this `fails requirement` "there is at least one asset input" + this `fails with` "there is at least one asset input" } // Check we can issue money only as long as the issuer institution is a command signer, i.e. any recognised // institution is allowed to issue as much cash as they want. transaction { output { outState } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Issue() } - this `fails requirement` "output deposits are owned by a command signer" + command(DUMMY_PUBKEY_1) { Cash.Commands.Issue() } + this `fails with` "output deposits are owned by a command signer" } transaction { output { @@ -88,11 +88,11 @@ class CashTests { ) } tweak { - arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue(0) } - this `fails requirement` "has a nonce" + command(MINI_CORP_PUBKEY) { Cash.Commands.Issue(0) } + this `fails with` "has a nonce" } - arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() } - this.accepts() + command(MINI_CORP_PUBKEY) { Cash.Commands.Issue() } + this.verifies() } // Test generation works. @@ -120,14 +120,14 @@ class CashTests { // Move fails: not allowed to summon money. tweak { - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this `fails requirement` "at issuer MegaCorp the amounts balance" + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this `fails with` "at issuer MegaCorp the amounts balance" } // Issue works. tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } - this.accepts() + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + this.verifies() } } @@ -135,36 +135,36 @@ class CashTests { transaction { input { inState } output { inState.copy(amount = inState.amount / 2) } - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } - this `fails requirement` "output values sum to more than the inputs" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + this `fails with` "output values sum to more than the inputs" } // Can't have an issue command that doesn't actually issue money. transaction { input { inState } output { inState } - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } - this `fails requirement` "output values sum to more than the inputs" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + this `fails with` "output values sum to more than the inputs" } // Can't have any other commands if we have an issue command (because the issue command overrules them) transaction { input { inState } output { inState.copy(amount = inState.amount * 2) } - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } - this `fails requirement` "there is only a single issue command" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + this `fails with` "there is only a single issue command" } tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } - this `fails requirement` "there is only a single issue command" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + this `fails with` "there is only a single issue command" } tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(inState.amount / 2) } - this `fails requirement` "there is only a single issue command" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(inState.amount / 2) } + this `fails with` "there is only a single issue command" } - this.accepts() + this.verifies() } } @@ -191,25 +191,25 @@ class CashTests { fun testMergeSplit() { // Splitting value works. transaction { - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } tweak { input { inState } for (i in 1..4) output { inState.copy(amount = inState.amount / 4) } - this.accepts() + this.verifies() } // Merging 4 inputs into 2 outputs works. tweak { for (i in 1..4) input { inState.copy(amount = inState.amount / 4) } output { inState.copy(amount = inState.amount / 2) } output { inState.copy(amount = inState.amount / 2) } - this.accepts() + this.verifies() } // Merging 2 inputs into 1 works. tweak { input { inState.copy(amount = inState.amount / 2) } input { inState.copy(amount = inState.amount / 2) } output { inState } - this.accepts() + this.verifies() } } } @@ -219,13 +219,13 @@ class CashTests { transaction { input { inState } input { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "zero sized inputs" + this `fails with` "zero sized inputs" } transaction { input { inState } output { inState } output { inState.copy(amount = 0.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "zero sized outputs" + this `fails with` "zero sized outputs" } } @@ -235,21 +235,21 @@ class CashTests { transaction { input { inState } output { outState `issued by` MINI_CORP } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at issuer MegaCorp the amounts balance" } // Can't change deposit reference when splitting. transaction { input { inState } output { outState.copy(amount = inState.amount / 2).editDepositRef(0) } output { outState.copy(amount = inState.amount / 2).editDepositRef(1) } - this `fails requirement` "for deposit [01] at issuer MegaCorp the amounts balance" + this `fails with` "for deposit [01] at issuer MegaCorp the amounts balance" } // Can't mix currencies. transaction { input { inState } output { outState.copy(amount = 800.DOLLARS `issued by` defaultIssuer) } output { outState.copy(amount = 200.POUNDS `issued by` defaultIssuer) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } transaction { input { inState } @@ -260,22 +260,22 @@ class CashTests { ) } output { outState.copy(amount = 1150.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } // Can't have superfluous input states from different issuers. transaction { input { inState } input { inState `issued by` MINI_CORP } output { outState } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this `fails requirement` "at issuer MiniCorp the amounts balance" + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this `fails with` "at issuer MiniCorp the amounts balance" } // Can't combine two different deposits at the same issuer. transaction { input { inState } input { inState.editDepositRef(3) } output { outState.copy(amount = inState.amount * 2).editDepositRef(3) } - this `fails requirement` "for deposit [01]" + this `fails with` "for deposit [01]" } } @@ -287,18 +287,18 @@ class CashTests { output { outState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) } tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this `fails requirement` "the amounts balance" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(100.DOLLARS `issued by` defaultIssuer) } + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this `fails with` "the amounts balance" } tweak { - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "required com.r3corda.contracts.cash.FungibleAsset.Commands.Move command" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) } + this `fails with` "required com.r3corda.contracts.asset.FungibleAsset.Commands.Move command" tweak { - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this.accepts() + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this.verifies() } } } @@ -310,15 +310,15 @@ class CashTests { output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) `issued by` MINI_CORP } output { inState.copy(amount = inState.amount - (200.DOLLARS `issued by` defaultIssuer)) } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at issuer MegaCorp the amounts balance" - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "at issuer MiniCorp the amounts balance" + command(MEGA_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` defaultIssuer) } + this `fails with` "at issuer MiniCorp the amounts balance" - arg(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) } - this.accepts() + command(MINI_CORP_PUBKEY) { Cash.Commands.Exit(200.DOLLARS `issued by` MINI_CORP.ref(defaultRef)) } + this.verifies() } } @@ -332,20 +332,20 @@ class CashTests { // Can't merge them together. tweak { output { inState.copy(owner = DUMMY_PUBKEY_2, amount = 2000.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at issuer MegaCorp the amounts balance" } // Missing MiniCorp deposit tweak { output { inState.copy(owner = DUMMY_PUBKEY_2) } output { inState.copy(owner = DUMMY_PUBKEY_2) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at issuer MegaCorp the amounts balance" } // This works. output { inState.copy(owner = DUMMY_PUBKEY_2) } output { inState.copy(owner = DUMMY_PUBKEY_2) `issued by` MINI_CORP } - arg(DUMMY_PUBKEY_1) { Cash.Commands.Move() } - this.accepts() + command(DUMMY_PUBKEY_1) { Cash.Commands.Move() } + this.verifies() } } @@ -358,9 +358,9 @@ class CashTests { input { pounds } output { inState `owned by` DUMMY_PUBKEY_2 } output { pounds `owned by` DUMMY_PUBKEY_1 } - arg(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Cash.Commands.Move() } + command(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Cash.Commands.Move() } - this.accepts() + this.verifies() } } diff --git a/experimental/src/test/kotlin/com/r3corda/contracts/ObligationTests.kt b/contracts/src/test/kotlin/com/r3corda/contracts/asset/ObligationTests.kt similarity index 57% rename from experimental/src/test/kotlin/com/r3corda/contracts/ObligationTests.kt rename to contracts/src/test/kotlin/com/r3corda/contracts/asset/ObligationTests.kt index 84be8b37df..5eec7d84c9 100644 --- a/experimental/src/test/kotlin/com/r3corda/contracts/ObligationTests.kt +++ b/contracts/src/test/kotlin/com/r3corda/contracts/asset/ObligationTests.kt @@ -1,15 +1,15 @@ -package com.r3corda.contracts +package com.r3corda.contracts.asset -import com.r3corda.contracts.cash.Cash -import com.r3corda.contracts.Obligation.Lifecycle +import com.r3corda.contracts.asset.Obligation.Lifecycle import com.r3corda.contracts.testing.* import com.r3corda.core.contracts.* import com.r3corda.core.crypto.SecureHash -import com.r3corda.core.seconds import com.r3corda.core.testing.* +import com.r3corda.core.testing.JavaTestHelpers import com.r3corda.core.utilities.nonEmptySetOf import org.junit.Test import java.security.PublicKey +import java.time.Duration import java.time.Instant import java.util.* import kotlin.test.* @@ -18,60 +18,64 @@ class ObligationTests { val defaultIssuer = MEGA_CORP.ref(1) val defaultUsd = USD `issued by` defaultIssuer val oneMillionDollars = 1000000.DOLLARS `issued by` defaultIssuer - val trustedCashContract = nonEmptySetOf(SecureHash.randomSHA256() as SecureHash) - val megaIssuedDollars = nonEmptySetOf(Issued(defaultIssuer, USD)) - val megaIssuedPounds = nonEmptySetOf(Issued(defaultIssuer, GBP)) + val trustedCashContract = nonEmptySetOf(SecureHash.Companion.randomSHA256() as SecureHash) + val megaIssuedDollars = nonEmptySetOf(Issued(defaultIssuer, USD)) + val megaIssuedPounds = nonEmptySetOf(Issued(defaultIssuer, GBP)) val fivePm = Instant.parse("2016-01-01T17:00:00.00Z") val sixPm = Instant.parse("2016-01-01T18:00:00.00Z") - val notary = MEGA_CORP val megaCorpDollarSettlement = Obligation.StateTemplate(trustedCashContract, megaIssuedDollars, fivePm) - val megaCorpPoundSettlement = megaCorpDollarSettlement.copy(acceptableIssuanceDefinitions = megaIssuedPounds) + val megaCorpPoundSettlement = megaCorpDollarSettlement.copy(acceptableIssuedProducts = megaIssuedPounds) val inState = Obligation.State( lifecycle = Lifecycle.NORMAL, - issuer = MEGA_CORP, + obligor = MEGA_CORP, template = megaCorpDollarSettlement, quantity = 1000.DOLLARS.quantity, - owner = DUMMY_PUBKEY_1 + beneficiary = DUMMY_PUBKEY_1 ) - val outState = inState.copy(owner = DUMMY_PUBKEY_2) + val outState = inState.copy(beneficiary = DUMMY_PUBKEY_2) - private fun obligationTestRoots(group: TransactionGroupDSL>) = group.Roots() - .transaction(oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) `with notary` DUMMY_NOTARY label "Alice's $1,000,000 obligation to Bob") - .transaction(oneMillionDollars.OBLIGATION `between` Pair(BOB, ALICE_PUBKEY) `with notary` DUMMY_NOTARY label "Bob's $1,000,000 obligation to Alice") - .transaction(oneMillionDollars.OBLIGATION `between` Pair(MEGA_CORP, BOB_PUBKEY) `with notary` DUMMY_NOTARY label "MegaCorp's $1,000,000 obligation to Bob") - .transaction(1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY label "Alice's $1,000,000") + private fun obligationTestRoots( + group: LedgerDSL + ) = group.apply { + unverifiedTransaction { + output("Alice's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY)) + output("Bob's $1,000,000 obligation to Alice", oneMillionDollars.OBLIGATION `between` Pair(BOB, ALICE_PUBKEY)) + output("MegaCorp's $1,000,000 obligation to Bob", oneMillionDollars.OBLIGATION `between` Pair(MEGA_CORP, BOB_PUBKEY)) + output("Alice's $1,000,000", 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` ALICE_PUBKEY) + } + } @Test fun trivial() { transaction { input { inState } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" tweak { output { outState.copy(quantity = 2000.DOLLARS.quantity) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } tweak { output { outState } - // No command arguments - this `fails requirement` "required com.r3corda.contracts.Obligation.Commands.Move command" + // No command commanduments + this `fails with` "required com.r3corda.contracts.asset.Obligation.Commands.Move command" } tweak { output { outState } - arg(DUMMY_PUBKEY_2) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "the owning keys are the same as the signing keys" + command(DUMMY_PUBKEY_2) { Obligation.Commands.Move(inState.issuanceDef) } + this `fails with` "the owning keys are the same as the signing keys" } tweak { output { outState } output { outState `issued by` MINI_CORP } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "at least one obligation input" + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + this `fails with` "at least one obligation input" } // Simple reallocation works. tweak { output { outState } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this.accepts() + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + this.verifies() } } } @@ -80,46 +84,49 @@ class ObligationTests { fun `issue debt`() { // Check we can't "move" debt into existence. transaction { - input { DummyContract.State() } + input { DummyState() } output { outState } - arg(MINI_CORP_PUBKEY) { Obligation.Commands.Move(outState.issuanceDef) } + command(MINI_CORP_PUBKEY) { Obligation.Commands.Move(outState.issuanceDef) } - this `fails requirement` "there is at least one obligation input" + this `fails with` "there is at least one obligation input" } // Check we can issue money only as long as the issuer institution is a command signer, i.e. any recognised // institution is allowed to issue as much cash as they want. transaction { output { outState } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Issue(outState.issuanceDef) } - this `fails requirement` "output deposits are owned by a command signer" + command(DUMMY_PUBKEY_1) { Obligation.Commands.Issue(outState.issuanceDef) } + this `fails with` "output deposits are owned by a command signer" } transaction { output { Obligation.State( - issuer = MINI_CORP, + obligor = MINI_CORP, quantity = 1000.DOLLARS.quantity, - owner = DUMMY_PUBKEY_1, + beneficiary = DUMMY_PUBKEY_1, template = megaCorpDollarSettlement ) } tweak { - arg(MINI_CORP_PUBKEY) { Obligation.Commands.Issue(Obligation.IssuanceDefinition(MINI_CORP, megaCorpDollarSettlement), 0) } - this `fails requirement` "has a nonce" + command(MINI_CORP_PUBKEY) { Obligation.Commands.Issue(Obligation.IssuanceDefinition(MINI_CORP, megaCorpDollarSettlement), 0) } + this `fails with` "has a nonce" } - arg(MINI_CORP_PUBKEY) { Obligation.Commands.Issue(Obligation.IssuanceDefinition(MINI_CORP, megaCorpDollarSettlement)) } - this.accepts() + command(MINI_CORP_PUBKEY) { Obligation.Commands.Issue(Obligation.IssuanceDefinition(MINI_CORP, megaCorpDollarSettlement)) } + this.verifies() } // Test generation works. val ptx = TransactionType.General.Builder(DUMMY_NOTARY) Obligation().generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, - owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY) + beneficiary = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY) assertTrue(ptx.inputStates().isEmpty()) - val s = ptx.outputStates()[0].data as Obligation.State - assertEquals(100.DOLLARS `issued by` MEGA_CORP.ref(1), s.amount) - assertEquals(MINI_CORP, s.issuer) - assertEquals(DUMMY_PUBKEY_1, s.owner) + val expected = Obligation.State( + obligor = MINI_CORP, + quantity = 100.DOLLARS.quantity, + beneficiary = DUMMY_PUBKEY_1, + template = megaCorpDollarSettlement + ) + assertEquals(ptx.outputStates()[0].data, expected) assertTrue(ptx.commands()[0].value is Obligation.Commands.Issue<*>) assertEquals(MINI_CORP_PUBKEY, ptx.commands()[0].signers[0]) @@ -130,14 +137,14 @@ class ObligationTests { // Move fails: not allowed to summon money. tweak { - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + this `fails with` "at obligor MegaCorp the amounts balance" } // Issue works. tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } - this.accepts() + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } + this.verifies() } } @@ -145,40 +152,40 @@ class ObligationTests { transaction { input { inState } output { inState.copy(quantity = inState.amount.quantity / 2) } - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } - this `fails requirement` "output values sum to more than the inputs" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } + this `fails with` "output values sum to more than the inputs" } // Can't have an issue command that doesn't actually issue money. transaction { input { inState } output { inState } - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } - this `fails requirement` "output values sum to more than the inputs" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } + this `fails with` "output values sum to more than the inputs" } // Can't have any other commands if we have an issue command (because the issue command overrules them) transaction { input { inState } output { inState.copy(quantity = inState.amount.quantity * 2) } - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } - this `fails requirement` "only move/exit commands can be present along with other obligation commands" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Issue(inState.issuanceDef) } + this `fails with` "only move/exit commands can be present along with other obligation commands" } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "only move/exit commands can be present along with other obligation commands" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Move(inState.issuanceDef) } + this `fails with` "only move/exit commands can be present along with other obligation commands" } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.SetLifecycle(inState.issuanceDef, Lifecycle.DEFAULTED) } - this `fails requirement` "only move/exit commands can be present along with other obligation commands" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.SetLifecycle(inState.issuanceDef, Lifecycle.DEFAULTED) } + this `fails with` "only move/exit commands can be present along with other obligation commands" } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, inState.amount / 2) } - this `fails requirement` "only move/exit commands can be present along with other obligation commands" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, inState.amount / 2) } + this `fails with` "only move/exit commands can be present along with other obligation commands" } - this.accepts() + this.verifies() } } @@ -189,18 +196,46 @@ class ObligationTests { @Test(expected = IllegalStateException::class) fun `reject issuance with inputs`() { // Issue some obligation - var ptx = TransactionType.General.Builder(DUMMY_NOTARY) - - Obligation().generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, - owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) - ptx.signWith(MINI_CORP_KEY) - val tx = ptx.toSignedTransaction() + val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generateIssue(this, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, + beneficiary = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) + signWith(MINI_CORP_KEY) + }.toSignedTransaction() // Include the previously issued obligation in a new issuance command - ptx = TransactionType.General.Builder(DUMMY_NOTARY) + val ptx = TransactionType.General.Builder(DUMMY_NOTARY) ptx.addInputState(tx.tx.outRef>(0)) Obligation().generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, - owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) + beneficiary = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) + } + + /** Test generating a transaction to net two obligations of the same size, and therefore there are no outputs. */ + @Test + fun `generate close-out net transaction`() { + val obligationAliceToBob = oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) + val obligationBobToAlice = oneMillionDollars.OBLIGATION `between` Pair(BOB, ALICE_PUBKEY) + val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generateCloseOutNetting(this, ALICE_PUBKEY, obligationAliceToBob, obligationBobToAlice) + signWith(ALICE_KEY) + signWith(DUMMY_NOTARY_KEY) + }.toSignedTransaction().tx + assertEquals(0, tx.outputs.size) + } + + /** Test generating a transaction to net two obligations of the different sizes, and confirm the balance is correct. */ + @Test + fun `generate close-out net transaction with remainder`() { + val obligationAliceToBob = (2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) + val obligationBobToAlice = oneMillionDollars.OBLIGATION `between` Pair(BOB, ALICE_PUBKEY) + val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generateCloseOutNetting(this, ALICE_PUBKEY, obligationAliceToBob, obligationBobToAlice) + signWith(ALICE_KEY) + signWith(DUMMY_NOTARY_KEY) + }.toSignedTransaction().tx + assertEquals(1, tx.outputs.size) + + val actual = tx.outputs[0].data + assertEquals((1000000.DOLLARS `issued by` defaultIssuer).OBLIGATION `between` Pair(ALICE, BOB_PUBKEY), actual) } /** Test generating a transaction to net two obligations of the same size, and therefore there are no outputs. */ @@ -208,9 +243,13 @@ class ObligationTests { fun `generate payment net transaction`() { val obligationAliceToBob = oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) val obligationBobToAlice = oneMillionDollars.OBLIGATION `between` Pair(BOB, ALICE_PUBKEY) - val ptx = TransactionType.General.Builder(DUMMY_NOTARY) - Obligation().generatePaymentNetting(ptx, defaultUsd, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice) - assertEquals(0, ptx.outputStates().size) + val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generatePaymentNetting(this, defaultUsd, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice) + signWith(ALICE_KEY) + signWith(BOB_KEY) + signWith(DUMMY_NOTARY_KEY) + }.toSignedTransaction().tx + assertEquals(0, tx.outputs.size) } /** Test generating a transaction to two obligations, where one is bigger than the other and therefore there is a remainder. */ @@ -218,238 +257,269 @@ class ObligationTests { fun `generate payment net transaction with remainder`() { val obligationAliceToBob = oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) val obligationBobToAlice = (2000000.DOLLARS `issued by` defaultIssuer).OBLIGATION `between` Pair(BOB, ALICE_PUBKEY) - val ptx = TransactionType.General.Builder(DUMMY_NOTARY) - Obligation().generatePaymentNetting(ptx, defaultUsd, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice) - assertEquals(1, ptx.outputStates().size) - val out = ptx.outputStates().single().data as Obligation.State - assertEquals(1000000.DOLLARS.quantity, out.quantity) - assertEquals(BOB, out.issuer) - assertEquals(ALICE_PUBKEY, out.owner) + val tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generatePaymentNetting(this, defaultUsd, DUMMY_NOTARY, obligationAliceToBob, obligationBobToAlice) + signWith(ALICE_KEY) + signWith(BOB_KEY) + }.toSignedTransaction().tx + assertEquals(1, tx.outputs.size) + val expected = obligationBobToAlice.copy(quantity = obligationBobToAlice.quantity - obligationAliceToBob.quantity) + val actual = tx.outputs[0].data + assertEquals(expected, actual) } /** Test generating a transaction to mark outputs as having defaulted. */ @Test fun `generate set lifecycle`() { - // Issue some obligation - val dueBefore = Instant.parse("2010-01-01T17:00:00Z") + // We don't actually verify the states, this is just here to make things look sensible + val dueBefore = TEST_TX_TIME - Duration.ofDays(7) // Generate a transaction issuing the obligation var tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { Obligation().generateIssue(this, MINI_CORP, megaCorpDollarSettlement.copy(dueBefore = dueBefore), 100.DOLLARS.quantity, - owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) + beneficiary = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) signWith(MINI_CORP_KEY) }.toSignedTransaction() var stateAndRef = tx.tx.outRef>(0) // Now generate a transaction marking the obligation as having defaulted tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { - Obligation().generateSetLifecycle(this, listOf(stateAndRef), Obligation.Lifecycle.DEFAULTED, DUMMY_NOTARY) + Obligation().generateSetLifecycle(this, listOf(stateAndRef), Lifecycle.DEFAULTED, DUMMY_NOTARY) signWith(MINI_CORP_KEY) - }.toSignedTransaction(false) + signWith(DUMMY_NOTARY_KEY) + }.toSignedTransaction() assertEquals(1, tx.tx.outputs.size) - assertEquals(stateAndRef.state.data.copy(lifecycle = Obligation.Lifecycle.DEFAULTED), tx.tx.outputs[0].data) + assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.DEFAULTED), tx.tx.outputs[0].data) + assertTrue(tx.verify().isEmpty()) // And set it back stateAndRef = tx.tx.outRef>(0) tx = TransactionType.General.Builder(DUMMY_NOTARY).apply { - Obligation().generateSetLifecycle(this, listOf(stateAndRef), Obligation.Lifecycle.NORMAL, DUMMY_NOTARY) + Obligation().generateSetLifecycle(this, listOf(stateAndRef), Lifecycle.NORMAL, DUMMY_NOTARY) signWith(MINI_CORP_KEY) - }.toSignedTransaction(false) + signWith(DUMMY_NOTARY_KEY) + }.toSignedTransaction() assertEquals(1, tx.tx.outputs.size) - assertEquals(stateAndRef.state.data.copy(lifecycle = Obligation.Lifecycle.NORMAL), tx.tx.outputs[0].data) + assertEquals(stateAndRef.state.data.copy(lifecycle = Lifecycle.NORMAL), tx.tx.outputs[0].data) + assertTrue(tx.verify().isEmpty()) } /** Test generating a transaction to settle an obligation. */ @Test fun `generate settlement transaction`() { - var ptx: TransactionBuilder - - // Generate a transaction to issue the cash we'll need - ptx = TransactionType.General.Builder(DUMMY_NOTARY) - Cash().generateIssue(ptx, 100.DOLLARS `issued by` defaultIssuer, MEGA_CORP_PUBKEY, DUMMY_NOTARY) - ptx.signWith(MEGA_CORP_KEY) - val cashTx = ptx.toSignedTransaction().tx + val cashTx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Cash().generateIssue(this, 100.DOLLARS `issued by` defaultIssuer, MINI_CORP_PUBKEY, DUMMY_NOTARY) + signWith(MEGA_CORP_KEY) + }.toSignedTransaction().tx // Generate a transaction issuing the obligation - ptx = TransactionType.General.Builder(DUMMY_NOTARY) - Obligation().generateIssue(ptx, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, - owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) - ptx.signWith(MINI_CORP_KEY) - val obligationTx = ptx.toSignedTransaction().tx + val obligationTx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generateIssue(this, MINI_CORP, megaCorpDollarSettlement, 100.DOLLARS.quantity, + beneficiary = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY) + signWith(MINI_CORP_KEY) + }.toSignedTransaction().tx // Now generate a transaction settling the obligation - ptx = TransactionType.General.Builder(DUMMY_NOTARY) - val stateAndRef = obligationTx.outRef>(0) - Obligation().generateSettle(ptx, listOf(obligationTx.outRef(0)), listOf(cashTx.outRef(0)), DUMMY_NOTARY) - assertEquals(2, ptx.inputStates().size) - assertEquals(1, ptx.outputStates().size) + val settleTx = TransactionType.General.Builder(DUMMY_NOTARY).apply { + Obligation().generateSettle(this, listOf(obligationTx.outRef(0)), listOf(cashTx.outRef(0)), Cash.Commands.Move(), DUMMY_NOTARY) + signWith(DUMMY_NOTARY_KEY) + signWith(MINI_CORP_KEY) + }.toSignedTransaction().tx + assertEquals(2, settleTx.inputs.size) + assertEquals(1, settleTx.outputs.size) } @Test fun `close-out netting`() { // Try netting out two obligations - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") // Note we can sign with either key here - arg(ALICE_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } + command(ALICE_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } timestamp(TEST_TX_TIME) + this.verifies() } - }.verify() + this.verifies() + } // Try netting out two obligations, with the third uninvolved obligation left // as-is - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") input("MegaCorp's $1,000,000 obligation to Bob") output("change") { oneMillionDollars.OBLIGATION `between` Pair(MEGA_CORP, BOB_PUBKEY) } - arg(BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } + command(BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } timestamp(TEST_TX_TIME) + this.verifies() } - }.verify() + this.verifies() + } // Try having outputs mis-match the inputs - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") output("change") { (oneMillionDollars / 2).OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) } - arg(BOB_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } + command(BOB_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } timestamp(TEST_TX_TIME) + this `fails with` "amounts owed on input and output must match" } - }.expectFailureOfTx(1, "amounts owed on input and output must match") + } // Have the wrong signature on the transaction - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.CLOSE_OUT) } timestamp(TEST_TX_TIME) + this `fails with` "any involved party has signed" } - }.expectFailureOfTx(1, "any involved party has signed") - + } } @Test fun `payment netting`() { // Try netting out two obligations - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") - arg(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } + command(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } timestamp(TEST_TX_TIME) + this.verifies() } - }.verify() + this.verifies() + } // Try netting out two obligations, but only provide one signature. Unlike close-out netting, we need both // signatures for payment netting - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Alice's $1,000,000 obligation to Bob") input("Bob's $1,000,000 obligation to Alice") - arg(BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } + command(BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } timestamp(TEST_TX_TIME) + this `fails with` "all involved parties have signed" } - }.expectFailureOfTx(1, "all involved parties have signed") + } // Multilateral netting, A -> B -> C which can net down to A -> C - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Bob's $1,000,000 obligation to Alice") input("MegaCorp's $1,000,000 obligation to Bob") output("MegaCorp's $1,000,000 obligation to Alice") { oneMillionDollars.OBLIGATION `between` Pair(MEGA_CORP, ALICE_PUBKEY) } - arg(ALICE_PUBKEY, BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } + command(ALICE_PUBKEY, BOB_PUBKEY, MEGA_CORP_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } timestamp(TEST_TX_TIME) + this.verifies() } - }.verify() + this.verifies() + } // Multilateral netting without the key of the receiving party - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Issuance") { input("Bob's $1,000,000 obligation to Alice") input("MegaCorp's $1,000,000 obligation to Bob") output("MegaCorp's $1,000,000 obligation to Alice") { oneMillionDollars.OBLIGATION `between` Pair(MEGA_CORP, ALICE_PUBKEY) } - arg(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } + command(ALICE_PUBKEY, BOB_PUBKEY) { Obligation.Commands.Net(NetType.PAYMENT) } timestamp(TEST_TX_TIME) + this `fails with` "all involved parties have signed" } - }.expectFailureOfTx(1, "all involved parties have signed") + } } @Test fun `settlement`() { // Try netting out two obligations - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Settlement") { input("Alice's $1,000,000 obligation to Bob") input("Alice's $1,000,000") output("Bob's $1,000,000") { 1000000.DOLLARS.CASH `issued by` defaultIssuer `owned by` BOB_PUBKEY } - arg(ALICE_PUBKEY) { Obligation.Commands.Settle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF), oneMillionDollars) } - arg(ALICE_PUBKEY) { Cash.Commands.Move(Obligation().legalContractReference) } + command(ALICE_PUBKEY) { Obligation.Commands.Settle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF), Amount(oneMillionDollars.quantity, USD)) } + command(ALICE_PUBKEY) { Cash.Commands.Move(Obligation().legalContractReference) } + this.verifies() } - }.verify() + this.verifies() + } } @Test fun `payment default`() { // Try defaulting an obligation without a timestamp - transactionGroupFor>() { + ledger { obligationTestRoots(this) transaction("Settlement") { input("Alice's $1,000,000 obligation to Bob") - output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY)).copy(lifecycle = Obligation.Lifecycle.DEFAULTED) } - arg(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF), Obligation.Lifecycle.DEFAULTED) } + output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY)).copy(lifecycle = Lifecycle.DEFAULTED) } + command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF), Lifecycle.DEFAULTED) } + this `fails with` "there is a timestamp from the authority" } - }.expectFailureOfTx(1, "there is a timestamp from the authority") + } - // Try defaulting an obligation - transactionGroupFor>() { - obligationTestRoots(this) + // Try defaulting an obligation due in the future + val pastTestTime = TEST_TX_TIME - Duration.ofDays(7) + val futureTestTime = TEST_TX_TIME + Duration.ofDays(7) + transaction("Settlement") { + input(oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) `at` futureTestTime) + output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) `at` futureTestTime).copy(lifecycle = Lifecycle.DEFAULTED) } + command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF) `at` futureTestTime, Lifecycle.DEFAULTED) } + timestamp(TEST_TX_TIME) + this `fails with` "the due date has passed" + } + + // Try defaulting an obligation that is now in the past + ledger { transaction("Settlement") { - input("Alice's $1,000,000 obligation to Bob") - output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY)).copy(lifecycle = Obligation.Lifecycle.DEFAULTED) } - arg(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF), Obligation.Lifecycle.DEFAULTED) } + input(oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) `at` pastTestTime) + output("Alice's defaulted $1,000,000 obligation to Bob") { (oneMillionDollars.OBLIGATION `between` Pair(ALICE, BOB_PUBKEY) `at` pastTestTime).copy(lifecycle = Lifecycle.DEFAULTED) } + command(BOB_PUBKEY) { Obligation.Commands.SetLifecycle(Obligation.IssuanceDefinition(ALICE, defaultUsd.OBLIGATION_DEF) `at` pastTestTime, Lifecycle.DEFAULTED) } timestamp(TEST_TX_TIME) + this.verifies() } - }.verify() + this.verifies() + } } @Test fun testMergeSplit() { // Splitting value works. transaction { - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } tweak { input { inState } - for (i in 1..4) output { inState.copy(quantity = inState.quantity / 4) } - this.accepts() + repeat(4) { output { inState.copy(quantity = inState.quantity / 4) } } + this.verifies() } // Merging 4 inputs into 2 outputs works. tweak { - for (i in 1..4) input { inState.copy(quantity = inState.quantity / 4) } + repeat(4) { input { inState.copy(quantity = inState.quantity / 4) } } output { inState.copy(quantity = inState.quantity / 2) } output { inState.copy(quantity = inState.quantity / 2) } - this.accepts() + this.verifies() } // Merging 2 inputs into 1 works. tweak { input { inState.copy(quantity = inState.quantity / 2) } input { inState.copy(quantity = inState.quantity / 2) } output { inState } - this.accepts() + this.verifies() } } } @@ -459,29 +529,30 @@ class ObligationTests { transaction { input { inState } input { inState.copy(quantity = 0L) } - this `fails requirement` "zero sized inputs" + this `fails with` "zero sized inputs" } transaction { input { inState } output { inState } output { inState.copy(quantity = 0L) } - this `fails requirement` "zero sized outputs" + this `fails with` "zero sized outputs" } } + @Test fun trivialMismatches() { // Can't change issuer. transaction { input { inState } output { outState `issued by` MINI_CORP } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at obligor MegaCorp the amounts balance" } // Can't mix currencies. transaction { input { inState } output { outState.copy(quantity = 80000, template = megaCorpDollarSettlement) } output { outState.copy(quantity = 20000, template = megaCorpPoundSettlement) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } transaction { input { inState } @@ -489,20 +560,20 @@ class ObligationTests { inState.copy( quantity = 15000, template = megaCorpPoundSettlement, - owner = DUMMY_PUBKEY_2 + beneficiary = DUMMY_PUBKEY_2 ) } output { outState.copy(quantity = 115000) } - this `fails requirement` "the amounts balance" + this `fails with` "the amounts balance" } // Can't have superfluous input states from different issuers. transaction { input { inState } input { inState `issued by` MINI_CORP } output { outState } - arg(DUMMY_PUBKEY_1) {Obligation.Commands.Move(inState.issuanceDef) } - arg(DUMMY_PUBKEY_1) {Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } - this `fails requirement` "at issuer MiniCorp the amounts balance" + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } + this `fails with` "at obligor MiniCorp the amounts balance" } } @@ -514,18 +585,18 @@ class ObligationTests { output { outState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 100.DOLLARS `issued by` defaultIssuer) } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "the amounts balance" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 100.DOLLARS) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + this `fails with` "the amounts balance" } tweak { - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 200.DOLLARS `issued by` defaultIssuer) } - this `fails requirement` "required com.r3corda.contracts.Obligation.Commands.Move command" + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 200.DOLLARS) } + this `fails with` "required com.r3corda.contracts.asset.Obligation.Commands.Move command" tweak { - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this.accepts() + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + this.verifies() } } } @@ -537,19 +608,19 @@ class ObligationTests { output { inState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) `issued by` MINI_CORP } output { inState.copy(quantity = inState.quantity - 200.DOLLARS.quantity) } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + this `fails with` "at obligor MegaCorp the amounts balance" - arg(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 200.DOLLARS `issued by` defaultIssuer) } + command(MEGA_CORP_PUBKEY) { Obligation.Commands.Exit(inState.issuanceDef, 200.DOLLARS) } tweak { - arg(MINI_CORP_PUBKEY) { Obligation.Commands.Exit((inState `issued by` MINI_CORP).issuanceDef, 0.DOLLARS `issued by` defaultIssuer) } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } - this `fails requirement` "at issuer MiniCorp the amounts balance" + command(MINI_CORP_PUBKEY) { Obligation.Commands.Exit((inState `issued by` MINI_CORP).issuanceDef, 0.DOLLARS) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } + this `fails with` "at obligor MiniCorp the amounts balance" } - arg(MINI_CORP_PUBKEY) { Obligation.Commands.Exit((inState `issued by` MINI_CORP).issuanceDef, 200.DOLLARS `issued by` defaultIssuer) } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } - this.accepts() + command(MINI_CORP_PUBKEY) { Obligation.Commands.Exit((inState `issued by` MINI_CORP).issuanceDef, 200.DOLLARS) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } + this.verifies() } } @@ -562,22 +633,22 @@ class ObligationTests { // Can't merge them together. tweak { - output { inState.copy(owner = DUMMY_PUBKEY_2, quantity = 200000L) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + output { inState.copy(beneficiary = DUMMY_PUBKEY_2, quantity = 200000L) } + this `fails with` "at obligor MegaCorp the amounts balance" } // Missing MiniCorp deposit tweak { - output { inState.copy(owner = DUMMY_PUBKEY_2) } - output { inState.copy(owner = DUMMY_PUBKEY_2) } - this `fails requirement` "at issuer MegaCorp the amounts balance" + output { inState.copy(beneficiary = DUMMY_PUBKEY_2) } + output { inState.copy(beneficiary = DUMMY_PUBKEY_2) } + this `fails with` "at obligor MegaCorp the amounts balance" } // This works. - output { inState.copy(owner = DUMMY_PUBKEY_2) } - output { inState.copy(owner = DUMMY_PUBKEY_2) `issued by` MINI_CORP } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } - arg(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } - this.accepts() + output { inState.copy(beneficiary = DUMMY_PUBKEY_2) } + output { inState.copy(beneficiary = DUMMY_PUBKEY_2) `issued by` MINI_CORP } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move(inState.issuanceDef) } + command(DUMMY_PUBKEY_1) { Obligation.Commands.Move((inState `issued by` MINI_CORP).issuanceDef) } + this.verifies() } } @@ -590,10 +661,10 @@ class ObligationTests { input { pounds } output { inState `owned by` DUMMY_PUBKEY_2 } output { pounds `owned by` DUMMY_PUBKEY_1 } - arg(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Obligation.Commands.Move(inState.issuanceDef) } - arg(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Obligation.Commands.Move(pounds.issuanceDef) } + command(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Obligation.Commands.Move(inState.issuanceDef) } + command(DUMMY_PUBKEY_1, DUMMY_PUBKEY_2) { Obligation.Commands.Move(pounds.issuanceDef) } - this.accepts() + this.verifies() } } @@ -626,12 +697,12 @@ class ObligationTests { // States must not be nettable if the cash contract differs assertNotEquals(fiveKDollarsFromMegaToMega.bilateralNetState, - fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableContracts = nonEmptySetOf(SecureHash.randomSHA256()))).bilateralNetState) + fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableContracts = nonEmptySetOf(SecureHash.Companion.randomSHA256()))).bilateralNetState) // States must not be nettable if the trusted issuers differ - val miniCorpIssuer = nonEmptySetOf(Issued(MINI_CORP.ref(1), USD)) + val miniCorpIssuer = nonEmptySetOf(Issued(MINI_CORP.ref(1), USD)) assertNotEquals(fiveKDollarsFromMegaToMega.bilateralNetState, - fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableIssuanceDefinitions = miniCorpIssuer)).bilateralNetState) + fiveKDollarsFromMegaToMega.copy(template = megaCorpDollarSettlement.copy(acceptableIssuedProducts = miniCorpIssuer)).bilateralNetState) } @Test(expected = IllegalStateException::class) @@ -686,7 +757,7 @@ class ObligationTests { val fiveKDollarsFromMegaToMini = Obligation.State(Lifecycle.NORMAL, MEGA_CORP, megaCorpDollarSettlement, 5000.DOLLARS.quantity, MINI_CORP_PUBKEY) val expected = mapOf(Pair(Pair(MEGA_CORP_PUBKEY, MINI_CORP_PUBKEY), fiveKDollarsFromMegaToMini.amount)) - val actual = extractAmountsDue(defaultUsd, listOf(fiveKDollarsFromMegaToMini)) + val actual = extractAmountsDue(USD, listOf(fiveKDollarsFromMegaToMini)) assertEquals(expected, actual) } @@ -697,8 +768,8 @@ class ObligationTests { Pair(Pair(ALICE_PUBKEY, BOB_PUBKEY), Amount(100000000, GBP)), Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(100000000, GBP)) ) - val expected: Map = emptyMap() // Zero balances are stripped before returning - val actual = sumAmountsDue(balanced) + val expected: Map, Amount> = emptyMap() // Zero balances are stripped before returning + val actual = netAmountsDue(balanced) assertEquals(expected, actual) } @@ -706,13 +777,13 @@ class ObligationTests { fun `netting difference balances due between parties`() { // Now try it with two balances, which cancel each other out val balanced = mapOf( - Pair(Pair(ALICE_PUBKEY, BOB_PUBKEY), Amount(100000000, GBP) `issued by` defaultIssuer), - Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(200000000, GBP) `issued by` defaultIssuer) + Pair(Pair(ALICE_PUBKEY, BOB_PUBKEY), Amount(100000000, GBP)), + Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(200000000, GBP)) ) val expected = mapOf( - Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(100000000, GBP) `issued by` defaultIssuer) + Pair(Pair(BOB_PUBKEY, ALICE_PUBKEY), Amount(100000000, GBP)) ) - var actual = netAmountsDue(balanced) + val actual = netAmountsDue(balanced) assertEquals(expected, actual) } diff --git a/core/build.gradle b/core/build.gradle index 84881b6925..33e81bafc6 100644 --- a/core/build.gradle +++ b/core/build.gradle @@ -1,9 +1,8 @@ -group 'com.r3cev.prototyping' -version '1.0-SNAPSHOT' - apply plugin: 'java' apply plugin: 'kotlin' apply plugin: QuasarPlugin +// Applying the maven plugin means this will get installed locally when running "gradle install" +apply plugin: 'maven' buildscript { repositories { @@ -24,8 +23,7 @@ repositories { dependencies { testCompile 'junit:junit:4.12' - testCompile 'org.assertj:assertj-core:3.4.1' - testCompile "commons-fileupload:commons-fileupload:1.3.1" + testCompile "commons-fileupload:commons-fileupload:1.3.2" // Guava: Google test library (collections test suite) testCompile "com.google.guava:guava-testlib:19.0" @@ -38,27 +36,27 @@ dependencies { compile "com.google.code.findbugs:jsr305:3.0.1" // AssertJ: for fluent assertions for testing - testCompile "org.assertj:assertj-core:3.4.1" + testCompile "org.assertj:assertj-core:${assertj_version}" // SLF4J: Logging framework. - compile "org.slf4j:slf4j-jdk14:1.7.13" + compile "org.slf4j:slf4j-jdk14:${slf4j_version}" // Guava: Google utilities library. compile "com.google.guava:guava:19.0" // RxJava: observable streams of events. - compile "io.reactivex:rxjava:1.0.17" + compile "io.reactivex:rxjava:1.1.6" // Kryo: object graph serialization. - compile "com.esotericsoftware:kryo:3.0.3" - compile "de.javakaffee:kryo-serializers:0.37" + compile "com.esotericsoftware:kryo:4.0.0" + compile "de.javakaffee:kryo-serializers:0.38" // 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. compile "org.apache.commons:commons-jexl3:3.0" // For JSON - compile "com.fasterxml.jackson.core:jackson-databind:2.5.5" + compile "com.fasterxml.jackson.core:jackson-databind:${jackson_version}" // Java ed25519 implementation. See https://github.com/str4d/ed25519-java/ compile 'net.i2p.crypto:eddsa:0.1.0' diff --git a/core/src/main/kotlin/com/r3corda/core/Utils.kt b/core/src/main/kotlin/com/r3corda/core/Utils.kt index e453006ec3..4598e15a2a 100644 --- a/core/src/main/kotlin/com/r3corda/core/Utils.kt +++ b/core/src/main/kotlin/com/r3corda/core/Utils.kt @@ -11,11 +11,9 @@ import java.io.InputStream import java.math.BigDecimal import java.nio.file.Files import java.nio.file.Path -import java.security.SecureRandom import java.time.Duration import java.time.temporal.Temporal import java.util.concurrent.Executor -import java.util.concurrent.locks.Lock import java.util.concurrent.locks.ReentrantLock import java.util.zip.ZipInputStream import kotlin.concurrent.withLock @@ -144,9 +142,13 @@ inline fun logElapsedTime(label: String, logger: Logger? = null, body: () -> * * val ii = state.locked { i } */ -class ThreadBox(content: T, val lock: Lock = ReentrantLock()) { +class ThreadBox(content: T, val lock: ReentrantLock = ReentrantLock()) { val content = content inline fun locked(body: T.() -> R): R = lock.withLock { body(content) } + inline fun alreadyLocked(body: T.() -> R): R { + check(lock.isHeldByCurrentThread, { "Expected $lock to already be locked." }) + return body(content) + } } /** @@ -177,16 +179,17 @@ class TransientProperty(private val initializer: () -> T) { * Given a path to a zip file, extracts it to the given directory. */ fun extractZipFile(zipPath: Path, toPath: Path) { - if (!Files.exists(toPath)) - Files.createDirectories(toPath) + val normalisedToPath = toPath.normalize() + if (!Files.exists(normalisedToPath)) + Files.createDirectories(normalisedToPath) ZipInputStream(BufferedInputStream(Files.newInputStream(zipPath))).use { zip -> while (true) { val e = zip.nextEntry ?: break - val outPath = toPath.resolve(e.name) + val outPath = normalisedToPath.resolve(e.name) // Security checks: we should reject a zip that contains tricksy paths that try to escape toPath. - if (!outPath.normalize().startsWith(toPath)) + if (!outPath.normalize().startsWith(normalisedToPath)) throw IllegalStateException("ZIP contained a path that resolved incorrectly: ${e.name}") if (e.isDirectory) { diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt b/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt index 370db1a055..529ad5f8df 100644 --- a/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt +++ b/core/src/main/kotlin/com/r3corda/core/contracts/ContractsDSL.kt @@ -60,14 +60,22 @@ inline fun requireThat(body: Requirements.() -> R) = R.body() //// Authenticated commands /////////////////////////////////////////////////////////////////////////////////////////// /** Filters the command list by type, party and public key all at once. */ -inline fun List>.select(signer: PublicKey? = null, +inline fun Collection>.select(signer: PublicKey? = null, party: Party? = null) = filter { it.value is T }. - filter { if (signer == null) true else it.signers.contains(signer) }. - filter { if (party == null) true else it.signingParties.contains(party) }. + filter { if (signer == null) true else signer in it.signers }. + filter { if (party == null) true else party in it.signingParties }. map { AuthenticatedObject(it.signers, it.signingParties, it.value as T) } -inline fun List>.requireSingleCommand() = try { +/** Filters the command list by type, parties and public keys all at once. */ +inline fun Collection>.select(signers: Collection?, + parties: Collection?) = + filter { it.value is T }. + filter { if (signers == null) true else it.signers.containsAll(signers)}. + filter { if (parties == null) true else it.signingParties.containsAll(parties) }. + map { AuthenticatedObject(it.signers, it.signingParties, it.value as T) } + +inline fun Collection>.requireSingleCommand() = try { select().single() } catch (e: NoSuchElementException) { throw IllegalStateException("Required ${T::class.qualifiedName} command") // Better error message. @@ -106,9 +114,10 @@ fun List>.getTimestampByName(vararg names: Stri */ @Throws(IllegalArgumentException::class) // TODO: Can we have a common Move command for all contracts and avoid the reified type parameter here? -inline fun verifyMoveCommand(inputs: List, tx: TransactionForContract) { - return verifyMoveCommand(inputs, tx.commands) -} +inline fun verifyMoveCommand(inputs: List, + tx: TransactionForContract) + : MoveCommand + = verifyMoveCommand(inputs, tx.commands) /** * Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key. @@ -116,13 +125,17 @@ inline fun verifyMoveCommand(inputs: List verifyMoveCommand(inputs: List, commands: List>) { +inline fun verifyMoveCommand(inputs: List, + commands: List>) + : MoveCommand { // Now check the digital signatures on the move command. Every input has an owning public key, and we must // see a signature from each of those keys. The actual signatures have been verified against the transaction // data by the platform before execution. val owningPubKeys = inputs.map { it.owner }.toSet() - val keysThatSigned = commands.requireSingleCommand().signers.toSet() + val command = commands.requireSingleCommand() + val keysThatSigned = command.signers.toSet() requireThat { "the owning keys are the same as the signing keys" by keysThatSigned.containsAll(owningPubKeys) } + return command.value } diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/DummyContract.kt b/core/src/main/kotlin/com/r3corda/core/contracts/DummyContract.kt index 41038e128b..66358cebd5 100644 --- a/core/src/main/kotlin/com/r3corda/core/contracts/DummyContract.kt +++ b/core/src/main/kotlin/com/r3corda/core/contracts/DummyContract.kt @@ -9,13 +9,12 @@ import java.security.PublicKey val DUMMY_PROGRAM_ID = DummyContract() class DummyContract : Contract { - data class State(val magicNumber: Int = 0) : ContractState { - override val contract = DUMMY_PROGRAM_ID - override val participants: List - get() = emptyList() + + interface State : ContractState { + val magicNumber: Int } - data class SingleOwnerState(val magicNumber: Int = 0, override val owner: PublicKey) : OwnableState { + data class SingleOwnerState(override val magicNumber: Int = 0, override val owner: PublicKey) : OwnableState, State { override val contract = DUMMY_PROGRAM_ID override val participants: List get() = listOf(owner) @@ -23,8 +22,13 @@ class DummyContract : Contract { override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner)) } - data class MultiOwnerState(val magicNumber: Int = 0, - val owners: List) : ContractState { + /** + * Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple + * participants, and could in theory be merged with [SingleOwnerState] by putting the additional participants + * in a different field, however this is a good example of a contract with multiple states. + */ + data class MultiOwnerState(override val magicNumber: Int = 0, + val owners: List) : ContractState, State { override val contract = DUMMY_PROGRAM_ID override val participants: List get() = owners diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/DummyState.kt b/core/src/main/kotlin/com/r3corda/core/contracts/DummyState.kt new file mode 100644 index 0000000000..1f6fb6df2c --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/contracts/DummyState.kt @@ -0,0 +1,12 @@ +package com.r3corda.core.contracts + +import java.security.PublicKey + +/** + * Dummy state for use in testing. Not part of any real contract. + */ +data class DummyState(val magicNumber: Int = 0) : ContractState { + override val contract = DUMMY_PROGRAM_ID + override val participants: List + get() = emptyList() +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt b/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt index 66ffcb817c..2048474434 100644 --- a/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt +++ b/core/src/main/kotlin/com/r3corda/core/contracts/Structures.kt @@ -3,6 +3,8 @@ package com.r3corda.core.contracts import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash import com.r3corda.core.crypto.toStringShort +import com.r3corda.core.protocols.ProtocolLogicRef +import com.r3corda.core.protocols.ProtocolLogicRefFactory import com.r3corda.core.serialization.OpaqueBytes import com.r3corda.core.serialization.serialize import java.io.FileNotFoundException @@ -57,7 +59,7 @@ interface ContractState { * is a miniature file system in which each file can be precisely mapped to the defining attachment. * * Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. - * The classfiles inside define not only [Contract] implementations but also the classes that define the states. + * The class files inside define not only [Contract] implementations but also the classes that define the states. * Within the rest of a transaction, user-providable components are referenced by name only. * * This means that a smart contract in Corda does two things: @@ -141,6 +143,33 @@ interface OwnableState : ContractState { fun withNewOwner(newOwner: PublicKey): Pair } +/** Something which is scheduled to happen at a point in time */ +interface Scheduled { + val scheduledAt: Instant +} + +/** + * Represents a contract state (unconsumed output) of type [LinearState] and a point in time that a lifecycle event is expected to take place + * for that contract state. + * + * This is effectively the input to a scheduler, which wakes up at that point in time and asks the contract state what + * lifecycle processing needs to take place. e.g. a fixing or a late payment etc. + */ +data class ScheduledStateRef(val ref: StateRef, override val scheduledAt: Instant) : Scheduled + +/** + * This class represents the lifecycle activity that a contract state of type [LinearState] would like to perform at a given point in time. + * e.g. run a fixing protocol + * + * Note the use of [ProtocolLogicRef] to represent a safe way to transport a [ProtocolLogic] out of the contract sandbox. + * + * Currently we support only protocol based activities as we expect there to be a transaction generated off the back of + * the activity, otherwise we have to start tracking secondary state on the platform of which scheduled activities + * for a particular [ContractState] have been processed/fired etc. If the activity is not "on ledger" then the + * scheduled activity shouldn't be either. + */ +data class ScheduledActivity(val logicRef: ProtocolLogicRef, override val scheduledAt: Instant) : Scheduled + /** * A state that evolves by superseding itself, all of which share the common "thread" * @@ -154,12 +183,24 @@ interface LinearState : ContractState { fun isRelevant(ourKeys: Set): Boolean } +interface SchedulableState : ContractState { + /** + * Indicate whether there is some activity to be performed at some future point in time with respect to this + * [ContractState], what that activity is and at what point in time it should be initiated. + * This can be used to implement deadlines for payment or processing of financial instruments according to a schedule. + * + * The state has no reference to it's own StateRef, so supply that for use as input to any ProtocolLogic constructed. + * + * @return null if there is no activity to schedule + */ + fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity? +} + /** * Interface representing an agreement that exposes various attributes that are common. Implementing it simplifies * implementation of general protocols that manipulate many agreement types. */ interface DealState : LinearState { - /** Human readable well known reference (e.g. trade reference) */ val ref: String @@ -187,8 +228,6 @@ interface DealState : LinearState { interface FixableDealState : DealState { /** * When is the next fixing and what is the fixing for? - * - * TODO: In future we would use this to register for an event to trigger a/the fixing protocol */ fun nextFixingOf(): FixOf? diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/TransactionBuilder.kt b/core/src/main/kotlin/com/r3corda/core/contracts/TransactionBuilder.kt index b66803898f..0d80a1cc92 100644 --- a/core/src/main/kotlin/com/r3corda/core/contracts/TransactionBuilder.kt +++ b/core/src/main/kotlin/com/r3corda/core/contracts/TransactionBuilder.kt @@ -15,6 +15,10 @@ import java.util.* * * The builder can be customised for specific transaction types, e.g. where additional processing is needed * before adding a state/command. + * + * @param notary The default notary that will be used for outputs that don't have a notary specified. When this is set, + * an output state can be added by just passing in a [ContractState] – a [TransactionState] with the + * default notary will be generated automatically. */ abstract class TransactionBuilder(protected val type: TransactionType = TransactionType.General(), protected val notary: Party? = null) { @@ -129,6 +133,7 @@ abstract class TransactionBuilder(protected val type: TransactionType = Transact fun addOutputState(state: ContractState, notary: Party) = addOutputState(TransactionState(state, notary)) + /** A default notary must be specified during builder construction to use this method */ fun addOutputState(state: ContractState) { checkNotNull(notary) { "Need to specify a Notary for the state, or set a default one on TransactionBuilder initialisation" } addOutputState(state, notary!!) diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/clauses/ClauseVerifier.kt b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/ClauseVerifier.kt new file mode 100644 index 0000000000..009115ed25 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/ClauseVerifier.kt @@ -0,0 +1,92 @@ +package com.r3corda.core.contracts.clauses + +import com.r3corda.core.contracts.* +import java.util.* + +interface Clause { + /** Classes for commands which must ALL be present in transaction for this clause to be triggered */ + val requiredCommands: Set> + /** Behaviour if this clause is matched */ + val ifNotMatched: MatchBehaviour + /** Behaviour if this clause is not matches */ + val ifMatched: MatchBehaviour +} + +enum class MatchBehaviour { + CONTINUE, + END, + ERROR +} + +interface SingleVerify { + /** + * Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause + * would check each of the output states that it applies to, looking for a zero amount, and throw IllegalStateException + * if any matched. + * + * @return the set of commands that are consumed IF this clause is matched, and cannot be used to match a + * later clause. This would normally be all commands matching "requiredCommands" for this clause, but some + * verify() functions may do further filtering on possible matches, and return a subset. This may also include + * commands that were not required (for example the Exit command for fungible assets is optional). + */ + @Throws(IllegalStateException::class) + fun verify(tx: TransactionForContract, + commands: Collection>): Set + +} + + +interface SingleClause : Clause, SingleVerify + +/** + * Abstract superclass for clause-based contracts to extend, which provides a verify() function + * that delegates to the supplied list of clauses. + */ +abstract class ClauseVerifier : Contract { + abstract val clauses: List + abstract fun extractCommands(tx: TransactionForContract): Collection> + override fun verify(tx: TransactionForContract) = verifyClauses(tx, clauses, extractCommands(tx)) +} + +/** + * Verify a transaction against the given list of clauses. + * + * @param tx transaction to be verified. + * @param clauses the clauses to verify. + * @param T common supertype of commands to extract from the transaction, which are of relevance to these clauses. + */ +inline fun verifyClauses(tx: TransactionForContract, + clauses: List) + = verifyClauses(tx, clauses, tx.commands.select()) + +/** + * Verify a transaction against the given list of clauses. + * + * @param tx transaction to be verified. + * @param clauses the clauses to verify. + * @param commands commands extracted from the transaction, which are relevant to the + * clauses. + */ +fun verifyClauses(tx: TransactionForContract, + clauses: List, + commands: Collection>) { + val unmatchedCommands = ArrayList(commands.map { it.value }) + + verify@ for (clause in clauses) { + val matchBehaviour = if (unmatchedCommands.map { command -> command.javaClass }.containsAll(clause.requiredCommands)) { + unmatchedCommands.removeAll(clause.verify(tx, commands)) + clause.ifMatched + } else { + clause.ifNotMatched + } + + when (matchBehaviour) { + MatchBehaviour.ERROR -> throw IllegalStateException() + MatchBehaviour.CONTINUE -> { + } + MatchBehaviour.END -> break@verify + } + } + + require(unmatchedCommands.isEmpty()) { "All commands must be matched at end of execution." } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/clauses/GroupClauseVerifier.kt b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/GroupClauseVerifier.kt new file mode 100644 index 0000000000..38bcf37262 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/GroupClauseVerifier.kt @@ -0,0 +1,82 @@ +package com.r3corda.core.contracts.clauses + +import com.r3corda.core.contracts.AuthenticatedObject +import com.r3corda.core.contracts.CommandData +import com.r3corda.core.contracts.ContractState +import com.r3corda.core.contracts.TransactionForContract +import java.util.* + +interface GroupVerify { + /** + * + * @return the set of commands that are consumed IF this clause is matched, and cannot be used to match a + * later clause. + */ + fun verify(tx: TransactionForContract, + inputs: List, + outputs: List, + commands: Collection>, + token: T): Set +} + +interface GroupClause : Clause, GroupVerify + +abstract class GroupClauseVerifier : SingleClause { + abstract val clauses: List> + override val requiredCommands: Set> + get() = emptySet() + + abstract fun extractGroups(tx: TransactionForContract): List> + + override fun verify(tx: TransactionForContract, commands: Collection>): Set { + val groups = extractGroups(tx) + val matchedCommands = HashSet() + val unmatchedCommands = ArrayList(commands.map { it.value }) + + for ((inputs, outputs, token) in groups) { + val temp = verifyGroup(commands, inputs, outputs, token, tx, unmatchedCommands) + matchedCommands.addAll(temp) + unmatchedCommands.removeAll(temp) + } + + return matchedCommands + } + + /** + * Verify a subset of a transaction's inputs and outputs matches the conditions from this clause. For example, a + * "no zero amount output" clause would check each of the output states within the group, looking for a zero amount, + * and throw IllegalStateException if any matched. + * + * @param commands the full set of commands which apply to this contract. + * @param inputs input states within this group. + * @param outputs output states within this group. + * @param token the object used as a key when grouping states. + * @param unmatchedCommands commands which have not yet been matched within this group. + * @return matchedCommands commands which are matched during the verification process. + */ + @Throws(IllegalStateException::class) + private fun verifyGroup(commands: Collection>, + inputs: List, + outputs: List, + token: T, + tx: TransactionForContract, + unmatchedCommands: List): Set { + val matchedCommands = HashSet() + verify@ for (clause in clauses) { + val matchBehaviour = if (unmatchedCommands.map { command -> command.javaClass }.containsAll(clause.requiredCommands)) { + matchedCommands.addAll(clause.verify(tx, inputs, outputs, commands, token)) + clause.ifMatched + } else { + clause.ifNotMatched + } + + when (matchBehaviour) { + MatchBehaviour.ERROR -> throw IllegalStateException() + MatchBehaviour.CONTINUE -> { + } + MatchBehaviour.END -> break@verify + } + } + return matchedCommands + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/contracts/clauses/InterceptorClause.kt b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/InterceptorClause.kt new file mode 100644 index 0000000000..9f9f4d3625 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/contracts/clauses/InterceptorClause.kt @@ -0,0 +1,28 @@ +package com.r3corda.core.contracts.clauses + +import com.r3corda.core.contracts.AuthenticatedObject +import com.r3corda.core.contracts.CommandData +import com.r3corda.core.contracts.TransactionForContract +import java.util.* + +/** + * A clause which intercepts calls to a wrapped clause, and passes them through verification + * only from a pre-clause. This is similar to an inceptor in aspect orientated programming. + */ +data class InterceptorClause( + val preclause: SingleVerify, + val clause: SingleClause +) : SingleClause { + override val ifNotMatched: MatchBehaviour + get() = clause.ifNotMatched + override val ifMatched: MatchBehaviour + get() = clause.ifMatched + override val requiredCommands: Set> + get() = clause.requiredCommands + + override fun verify(tx: TransactionForContract, commands: Collection>): Set { + val consumed = HashSet(preclause.verify(tx, commands)) + consumed.addAll(clause.verify(tx, commands)) + return consumed + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/crypto/CryptoUtilities.kt b/core/src/main/kotlin/com/r3corda/core/crypto/CryptoUtilities.kt index 0f81331f5f..11022a2086 100644 --- a/core/src/main/kotlin/com/r3corda/core/crypto/CryptoUtilities.kt +++ b/core/src/main/kotlin/com/r3corda/core/crypto/CryptoUtilities.kt @@ -5,9 +5,9 @@ import com.r3corda.core.serialization.OpaqueBytes import com.r3corda.core.serialization.SerializedBytes import com.r3corda.core.serialization.deserialize import net.i2p.crypto.eddsa.EdDSAEngine +import net.i2p.crypto.eddsa.EdDSAPublicKey import java.math.BigInteger import java.security.* -import java.security.interfaces.ECPublicKey import net.i2p.crypto.eddsa.KeyPairGenerator as EddsaKeyPairGenerator fun newSecureRandom(): SecureRandom { @@ -158,8 +158,8 @@ fun PublicKey.verifyWithECDSA(content: ByteArray, signature: DigitalSignature) { /** Render a public key to a string, using a short form if it's an elliptic curve public key */ fun PublicKey.toStringShort(): String { - return (this as? ECPublicKey)?.let { key -> - "DL" + Base58.encode(key.w.affineX.toByteArray()) // DL -> Distributed Ledger + return (this as? EdDSAPublicKey)?.let { key -> + "DL" + Base58.encode(key.abyte) // DL -> Distributed Ledger } ?: toString() } diff --git a/core/src/main/kotlin/com/r3corda/core/node/CordaPluginRegistry.kt b/core/src/main/kotlin/com/r3corda/core/node/CordaPluginRegistry.kt new file mode 100644 index 0000000000..89492ee373 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/node/CordaPluginRegistry.kt @@ -0,0 +1,23 @@ +package com.r3corda.core.node + +/** + * Implement this interface on a class advertised in a META-INF/services/com.r3corda.core.node.CordaPluginRegistry file + * to extend a Corda node with additional application services. + */ +interface CordaPluginRegistry { + /** + * List of JAX-RS classes inside the contract jar. They are expected to have a single parameter constructor that takes a ServiceHub as input. + * These are listed as Class<*>, because they will be instantiated inside an AttachmentClassLoader so that subsequent protocols, contracts, etc + * will be running in the appropriate isolated context. + */ + val webApis: List> + + /** + * A Map with an entry for each consumed protocol used by the webAPIs. + * The key of each map entry should contain the ProtocolLogic class name. + * The associated map values are the union of all concrete class names passed to the protocol constructor. + * Standard java.lang.* and kotlin.* types do not need to be included explicitly + * This is used to extend the white listed protocols that can be initiated from the ServiceHub invokeProtocolAsync method + */ + val requiredProtocols: Map> +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt b/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt index 3e80aa0644..d1cf7fa0fd 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/ServiceHub.kt @@ -1,8 +1,10 @@ package com.r3corda.core.node +import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.contracts.* import com.r3corda.core.messaging.MessagingService import com.r3corda.core.node.services.* +import com.r3corda.core.protocols.ProtocolLogic import java.time.Clock /** @@ -20,6 +22,7 @@ interface ServiceHub { val storageService: StorageService val networkService: MessagingService val networkMapCache: NetworkMapCache + val schedulerService: SchedulerService val clock: Clock /** @@ -60,4 +63,11 @@ interface ServiceHub { val definingTx = storageService.validatedTransactions.getTransaction(stateRef.txhash) ?: throw TransactionResolutionException(stateRef.txhash) return definingTx.tx.outputs[stateRef.index] } + + /** + * Will check [logicType] and [args] against a whitelist and if acceptable then construct and initiate the protocol. + * + * @throws IllegalProtocolLogicException or IllegalArgumentException if there are problems with the [logicType] or [args] + */ + fun invokeProtocolAsync(logicType: Class>, vararg args: Any?): ListenableFuture } \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt b/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt index 8bb335b309..deff8a419a 100644 --- a/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt +++ b/core/src/main/kotlin/com/r3corda/core/node/services/Services.kt @@ -1,5 +1,7 @@ package com.r3corda.core.node.services +import com.google.common.util.concurrent.ListenableFuture +import com.google.common.util.concurrent.SettableFuture import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash @@ -113,6 +115,17 @@ interface WalletService { * the update. */ val updates: rx.Observable + + /** + * Provide a [Future] for when a [StateRef] is consumed, which can be very useful in building tests. + */ + fun whenConsumed(ref: StateRef): ListenableFuture { + val future = SettableFuture.create() + updates.filter { ref in it.consumed }.first().subscribe { + future.set(it) + } + return future + } } inline fun WalletService.linearHeadsOfType() = linearHeadsOfType_(T::class.java) @@ -156,6 +169,7 @@ interface StorageService { * Returns the legal identity that this node is configured with. Assumed to be initialised when the node is * first installed. */ + //TODO this should be in the IdentityService, or somewhere not here val myLegalIdentity: Party val myLegalIdentityKey: KeyPair } @@ -172,4 +186,24 @@ interface TxWritableStorageService : StorageService { override val validatedTransactions: TransactionStorage } +/** + * Provides access to schedule activity at some point in time. This interface might well be expanded to + * increase the feature set in the future. + * + * If the point in time is in the past, the expectation is that the activity will happen shortly after it is scheduled. + * + * The main consumer initially is an observer of the wallet to schedule activities based on transactions as they are + * recorded. + */ +interface SchedulerService { + /** + * Schedule a new activity for a TX output, probably because it was just produced. + * + * Only one activity can be scheduled for a particular [StateRef] at any one time. Scheduling a [ScheduledStateRef] + * replaces any previously scheduled [ScheduledStateRef] for any one [StateRef]. + */ + fun scheduleStateActivity(action: ScheduledStateRef) + /** Unschedule all activity for a TX output, probably because it was consumed. */ + fun unscheduleStateActivity(ref: StateRef) +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogic.kt b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogic.kt index d602e040ef..c07cf36d86 100644 --- a/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogic.kt +++ b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogic.kt @@ -1,7 +1,7 @@ package com.r3corda.core.protocols import co.paralleluniverse.fibers.Suspendable -import com.r3corda.core.messaging.MessageRecipients +import com.r3corda.core.crypto.Party import com.r3corda.core.node.ServiceHub import com.r3corda.core.utilities.ProgressTracker import com.r3corda.core.utilities.UntrustworthyData @@ -25,6 +25,7 @@ import org.slf4j.Logger * it to the [subProtocol] method. It will return the result of that protocol when it completes. */ abstract class ProtocolLogic { + /** Reference to the [Fiber] instance that is the top level controller for the entire flow. */ lateinit var psm: ProtocolStateMachine<*> @@ -38,22 +39,30 @@ abstract class ProtocolLogic { */ val serviceHub: ServiceHub get() = psm.serviceHub + /** + * The topic to use when communicating with other parties. If more than one topic is required then use sub-protocols. + * Note that this is temporary until protocol sessions are properly implemented. + */ + protected abstract val topic: String + // Kotlin helpers that allow the use of generic types. - inline fun sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, - sessionIDForReceive: Long, obj: Any): UntrustworthyData { - return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, obj, T::class.java) + inline fun sendAndReceive(destination: Party, + sessionIDForSend: Long, + sessionIDForReceive: Long, + payload: Any): UntrustworthyData { + return psm.sendAndReceive(topic, destination, sessionIDForSend, sessionIDForReceive, payload, T::class.java) } - inline fun receive(topic: String, sessionIDForReceive: Long): UntrustworthyData { - return receive(topic, sessionIDForReceive, T::class.java) + inline fun receive(sessionIDForReceive: Long): UntrustworthyData { + return receive(sessionIDForReceive, T::class.java) } - @Suspendable fun receive(topic: String, sessionIDForReceive: Long, clazz: Class): UntrustworthyData { - return psm.receive(topic, sessionIDForReceive, clazz) + @Suspendable fun receive(sessionIDForReceive: Long, receiveType: Class): UntrustworthyData { + return psm.receive(topic, sessionIDForReceive, receiveType) } - @Suspendable fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) { - psm.send(topic, destination, sessionID, obj) + @Suspendable fun send(destination: Party, sessionID: Long, payload: Any) { + psm.send(topic, destination, sessionID, payload) } /** @@ -71,9 +80,15 @@ abstract class ProtocolLogic { private fun maybeWireUpProgressTracking(subLogic: ProtocolLogic<*>) { val ours = progressTracker + val theirs = subLogic.progressTracker - if (ours != null && theirs != null) + if (ours != null && theirs != null) { + if (ours.currentStep == ProgressTracker.UNSTARTED) { + logger.warn("ProgressTracker has not been started for $this") + ours.nextStep() + } ours.setChildProgressTracker(ours.currentStep, theirs) + } } /** @@ -90,4 +105,5 @@ abstract class ProtocolLogic { /** This is where you fill out your business logic. */ @Suspendable abstract fun call(): T + } \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogicRef.kt b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogicRef.kt new file mode 100644 index 0000000000..5b0154cb81 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolLogicRef.kt @@ -0,0 +1,169 @@ +package com.r3corda.core.protocols + +import com.google.common.primitives.Primitives +import com.r3corda.core.contracts.StateRef +import com.r3corda.core.crypto.SecureHash +import com.r3corda.core.serialization.SingletonSerializeAsToken +import com.r3corda.protocols.TwoPartyDealProtocol +import java.lang.reflect.ParameterizedType +import java.lang.reflect.Type +import java.time.Duration +import java.util.* +import kotlin.reflect.KFunction +import kotlin.reflect.KParameter +import kotlin.reflect.jvm.javaType +import kotlin.reflect.primaryConstructor + +/** + * A class for conversion to and from [ProtocolLogic] and [ProtocolLogicRef] instances + * + * Validation of types is performed on the way in and way out in case this object is passed between JVMs which might have differing + * whitelists. + * + * TODO: Ways to populate whitelist of "blessed" protocols per node/party + * TODO: Ways to populate argument types whitelist. Per node/party or global? + * TODO: Align with API related logic for passing in ProtocolLogic references (ProtocolRef) + * TODO: Actual support for AppContext / AttachmentsClassLoader + */ +class ProtocolLogicRefFactory(private val protocolWhitelist: Map>) : SingletonSerializeAsToken() { + + constructor() : this(mapOf(Pair(TwoPartyDealProtocol.FixingRoleDecider::class.java.name, setOf(StateRef::class.java.name, Duration::class.java.name)))) + + // Pending real dependence on AppContext for class loading etc + @Suppress("UNUSED_PARAMETER") + private fun validateProtocolClassName(className: String, appContext: AppContext) { + // TODO: make this specific to the attachments in the [AppContext] by including [SecureHash] in whitelist check + require(protocolWhitelist.containsKey(className)) { "${ProtocolLogic::class.java.simpleName} of ${ProtocolLogicRef::class.java.simpleName} must have type on the whitelist: $className" } + } + + // Pending real dependence on AppContext for class loading etc + @Suppress("UNUSED_PARAMETER") + private fun validateArgClassName(className: String, argClassName: String, appContext: AppContext) { + // TODO: consider more carefully what to whitelist and how to secure protocols + // For now automatically accept standard java.lang.* and kotlin.* types. + // All other types require manual specification at ProtocolLogicRefFactory construction time. + if (argClassName.startsWith("java.lang.") || argClassName.startsWith("kotlin.")) { + return + } + // TODO: make this specific to the attachments in the [AppContext] by including [SecureHash] in whitelist check + require(protocolWhitelist[className]!!.contains(argClassName)) { "Args to ${className} must have types on the args whitelist: $argClassName" } + } + + /** + * Create a [ProtocolLogicRef] for the Kotlin primary constructor or Java constructor and the given args. + */ + fun create(type: Class>, vararg args: Any?): ProtocolLogicRef { + val constructor = type.kotlin.primaryConstructor ?: return createJava(type, *args) + if (constructor.parameters.size < args.size) { + throw IllegalProtocolLogicException(type, "due to too many arguments supplied to kotlin primary constructor") + } + // Build map of args from array + val argsMap = args.zip(constructor.parameters).map { Pair(it.second.name!!, it.first) }.toMap() + return createKotlin(type, argsMap) + } + + /** + * Create a [ProtocolLogicRef] by trying to find a Kotlin constructor that matches the given args. + * + * TODO: Rethink language specific naming. + */ + fun createKotlin(type: Class>, args: Map): ProtocolLogicRef { + // TODO: we need to capture something about the class loader or "application context" into the ref, + // perhaps as some sort of ThreadLocal style object. For now, just create an empty one. + val appContext = AppContext(emptyList()) + validateProtocolClassName(type.name, appContext) + // Check we can find a constructor and populate the args to it, but don't call it + createConstructor(appContext, type, args) + return ProtocolLogicRef(type.name, appContext, args) + } + + /** + * Create a [ProtocolLogicRef] by trying to find a Java constructor that matches the given args. + */ + private fun createJava(type: Class>, vararg args: Any?): ProtocolLogicRef { + // Build map for each + val argsMap = HashMap(args.size) + var index = 0 + args.forEach { argsMap["arg${index++}"] = it } + return createKotlin(type, argsMap) + } + + fun toProtocolLogic(ref: ProtocolLogicRef): ProtocolLogic<*> { + validateProtocolClassName(ref.protocolLogicClassName, ref.appContext) + val klass = Class.forName(ref.protocolLogicClassName, true, ref.appContext.classLoader).asSubclass(ProtocolLogic::class.java) + return createConstructor(ref.appContext, klass, ref.args)() + } + + private fun createConstructor(appContext: AppContext, clazz: Class>, args: Map): () -> ProtocolLogic<*> { + for (constructor in clazz.kotlin.constructors) { + val params = buildParams(appContext, clazz, constructor, args) ?: continue + // If we get here then we matched every parameter + return { constructor.callBy(params) } + } + throw IllegalProtocolLogicException(clazz, "as could not find matching constructor for: $args") + } + + private fun buildParams(appContext: AppContext, clazz: Class>, constructor: KFunction>, args: Map): HashMap? { + val params = hashMapOf() + val usedKeys = hashSetOf() + for (parameter in constructor.parameters) { + if (!tryBuildParam(args, parameter, params)) { + return null + } else { + usedKeys += parameter.name!! + } + } + if ((args.keys - usedKeys).isNotEmpty()) { + // Not all args were used + return null + } + params.values.forEach { if (it is Any) validateArgClassName(clazz.name, it.javaClass.name, appContext) } + return params + } + + private fun tryBuildParam(args: Map, parameter: KParameter, params: HashMap): Boolean { + val containsKey = parameter.name in args + // OK to be missing if optional + return (parameter.isOptional && !containsKey) || (containsKey && paramCanBeBuilt(args, parameter, params)) + } + + private fun paramCanBeBuilt(args: Map, parameter: KParameter, params: HashMap): Boolean { + val value = args[parameter.name] + params[parameter] = value + return (value is Any && parameterAssignableFrom(parameter.type.javaType, value)) || parameter.type.isMarkedNullable + } + + private fun parameterAssignableFrom(type: Type, value: Any): Boolean { + if (type is Class<*>) { + if (type.isPrimitive) { + return Primitives.unwrap(value.javaClass) == type + } else { + return type.isAssignableFrom(value.javaClass) + } + } else if (type is ParameterizedType) { + return parameterAssignableFrom(type.rawType, value) + } else { + return false + } + } +} + +class IllegalProtocolLogicException(type: Class<*>, msg: String) : IllegalArgumentException("${ProtocolLogicRef::class.java.simpleName} cannot be constructed for ${ProtocolLogic::class.java.simpleName} of type ${type.name} $msg") + +/** + * A class representing a [ProtocolLogic] instance which would be possible to safely pass out of the contract sandbox + * + * Only allows a String reference to the ProtocolLogic class, and only allows restricted argument types as per [ProtocolLogicRefFactory] + */ +// TODO: align this with the existing [ProtocolRef] in the bank-side API (probably replace some of the API classes) +data class ProtocolLogicRef internal constructor(val protocolLogicClassName: String, val appContext: AppContext, val args: Map) + +/** + * This is just some way to track what attachments need to be in the class loader, but may later include some app + * properties loaded from the attachments. And perhaps the authenticated user for an API call? + */ +data class AppContext(val attachments: List) { + // TODO: build a real [AttachmentsClassLoader] etc + val classLoader: ClassLoader + get() = this.javaClass.classLoader +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolStateMachine.kt b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolStateMachine.kt index fc4f8039e8..217df1752d 100644 --- a/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolStateMachine.kt +++ b/core/src/main/kotlin/com/r3corda/core/protocols/ProtocolStateMachine.kt @@ -1,7 +1,7 @@ package com.r3corda.core.protocols import co.paralleluniverse.fibers.Suspendable -import com.r3corda.core.messaging.MessageRecipients +import com.r3corda.core.crypto.Party import com.r3corda.core.node.ServiceHub import com.r3corda.core.utilities.UntrustworthyData import org.slf4j.Logger @@ -12,14 +12,14 @@ import org.slf4j.Logger */ interface ProtocolStateMachine { @Suspendable - fun sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, - obj: Any, recvType: Class): UntrustworthyData + fun sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, + payload: Any, recvType: Class): UntrustworthyData @Suspendable fun receive(topic: String, sessionIDForReceive: Long, recvType: Class): UntrustworthyData @Suspendable - fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) + fun send(topic: String, destination: Party, sessionID: Long, payload: Any) val serviceHub: ServiceHub val logger: Logger diff --git a/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt b/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt index 2e555156e7..904741d06a 100644 --- a/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt +++ b/core/src/main/kotlin/com/r3corda/core/serialization/Kryo.kt @@ -360,10 +360,6 @@ fun createKryo(k: Kryo = Kryo()): Kryo { // This is required to make all the unit tests pass register(Party::class.java) - // Work around a bug in Kryo handling nested generics - register(Issued::class.java, ImmutableClassSerializer(Issued::class)) - register(TransactionState::class.java, ImmutableClassSerializer(TransactionState::class)) - // This ensures a NonEmptySetSerializer is constructed with an initial value. register(NonEmptySet::class.java, NonEmptySetSerializer) diff --git a/core/src/main/kotlin/com/r3corda/core/testing/LedgerDSLInterpreter.kt b/core/src/main/kotlin/com/r3corda/core/testing/LedgerDSLInterpreter.kt new file mode 100644 index 0000000000..d41ad3cd60 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/testing/LedgerDSLInterpreter.kt @@ -0,0 +1,39 @@ +package com.r3corda.core.testing + +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.SecureHash +import java.io.InputStream + +interface OutputStateLookup { + fun retrieveOutputStateAndRef(clazz: Class, label: String): StateAndRef +} + +interface LedgerDSLInterpreter> : OutputStateLookup { + fun transaction(transactionLabel: String?, dsl: TransactionDSL.() -> R): WireTransaction + fun unverifiedTransaction(transactionLabel: String?, dsl: TransactionDSL.() -> Unit): WireTransaction + fun tweak(dsl: LedgerDSL>.() -> Unit) + fun attachment(attachment: InputStream): SecureHash + fun verifies() +} + +/** + * This is the class the top-level primitives deal with. It delegates all other primitives to the contained interpreter. + * This way we have a decoupling of the DSL "AST" and the interpretation(s) of it. Note how the delegation forces + * covariance of the TransactionInterpreter parameter. + * + * TODO (Kotlin 1.1): Use type synonyms to make the type params less unwieldy + */ +class LedgerDSL, out L : LedgerDSLInterpreter> (val interpreter: L) : + LedgerDSLInterpreter> by interpreter { + + fun transaction(dsl: TransactionDSL>.() -> R) = + transaction(null, dsl) + fun unverifiedTransaction(dsl: TransactionDSL>.() -> Unit) = + unverifiedTransaction(null, dsl) + + inline fun String.outputStateAndRef(): StateAndRef = + retrieveOutputStateAndRef(S::class.java, this) + inline fun String.output(): TransactionState = + outputStateAndRef().state + fun String.outputRef(): StateRef = outputStateAndRef().ref +} diff --git a/core/src/main/kotlin/com/r3corda/core/testing/TestDSL.kt b/core/src/main/kotlin/com/r3corda/core/testing/TestDSL.kt new file mode 100644 index 0000000000..564524dc85 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/testing/TestDSL.kt @@ -0,0 +1,354 @@ +package com.r3corda.core.testing + +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.DigitalSignature +import com.r3corda.core.crypto.Party +import com.r3corda.core.crypto.SecureHash +import com.r3corda.core.crypto.signWithECDSA +import com.r3corda.core.node.services.IdentityService +import com.r3corda.core.node.services.StorageService +import com.r3corda.core.node.services.testing.MockStorageService +import com.r3corda.core.serialization.serialize +import java.io.InputStream +import java.security.KeyPair +import java.security.PublicKey +import java.util.* + +fun transaction( + transactionLabel: String? = null, + dsl: TransactionDSL< + EnforceVerifyOrFail, + TransactionDSLInterpreter + >.() -> EnforceVerifyOrFail +) = JavaTestHelpers.transaction(transactionLabel, dsl) + +fun ledger( + identityService: IdentityService = MOCK_IDENTITY_SERVICE, + storageService: StorageService = MockStorageService(), + dsl: LedgerDSL.() -> Unit +) = JavaTestHelpers.ledger(identityService, storageService, dsl) + +@Deprecated( + message = "ledger doesn't nest, use tweak", + replaceWith = ReplaceWith("tweak"), + level = DeprecationLevel.ERROR) +@Suppress("UNUSED_PARAMETER") +fun TransactionDSLInterpreter.ledger( + dsl: LedgerDSL.() -> Unit) { +} + +@Deprecated( + message = "transaction doesn't nest, use tweak", + replaceWith = ReplaceWith("tweak"), + level = DeprecationLevel.ERROR) +@Suppress("UNUSED_PARAMETER") +fun TransactionDSLInterpreter.transaction( + dsl: TransactionDSL< + EnforceVerifyOrFail, + TransactionDSLInterpreter + >.() -> EnforceVerifyOrFail) { +} + +@Deprecated( + message = "ledger doesn't nest, use tweak", + replaceWith = ReplaceWith("tweak"), + level = DeprecationLevel.ERROR) +@Suppress("UNUSED_PARAMETER") +fun LedgerDSLInterpreter>.ledger( + dsl: LedgerDSL.() -> Unit) { +} + +/** + * If you jumped here from a compiler error make sure the last line of your test tests for a transaction verify or fail + * This is a dummy type that can only be instantiated by functions in this module. This way we can ensure that all tests + * will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of + * the triggered diagnostic. + */ +sealed class EnforceVerifyOrFail { + internal object Token: EnforceVerifyOrFail() +} + +/** + * This interpreter builds a transaction, and [TransactionDSL.verifies] that the resolved transaction is correct. Note + * that transactions corresponding to input states are not verified. Use [LedgerDSL.verifies] for that. + */ +data class TestTransactionDSLInterpreter( + override val ledgerInterpreter: TestLedgerDSLInterpreter, + private val inputStateRefs: ArrayList = arrayListOf(), + internal val outputStates: ArrayList = arrayListOf(), + private val attachments: ArrayList = arrayListOf(), + private val commands: ArrayList = arrayListOf(), + private val signers: LinkedHashSet = LinkedHashSet(), + private val transactionType: TransactionType = TransactionType.General() +) : TransactionDSLInterpreter, OutputStateLookup by ledgerInterpreter { + private fun copy(): TestTransactionDSLInterpreter = + TestTransactionDSLInterpreter( + ledgerInterpreter = ledgerInterpreter, + inputStateRefs = ArrayList(inputStateRefs), + outputStates = ArrayList(outputStates), + attachments = ArrayList(attachments), + commands = ArrayList(commands), + signers = LinkedHashSet(signers), + transactionType = transactionType + ) + + internal fun toWireTransaction(): WireTransaction = + WireTransaction( + inputs = inputStateRefs, + outputs = outputStates.map { it.state }, + attachments = attachments, + commands = commands, + signers = signers.toList(), + type = transactionType + ) + + override fun input(stateRef: StateRef) { + val notary = ledgerInterpreter.resolveStateRef(stateRef).notary + signers.add(notary.owningKey) + inputStateRefs.add(stateRef) + } + + override fun _output(label: String?, notary: Party, contractState: ContractState) { + outputStates.add(LabeledOutput(label, TransactionState(contractState, notary))) + } + + override fun attachment(attachmentId: SecureHash) { + attachments.add(attachmentId) + } + + override fun _command(signers: List, commandData: CommandData) { + this.signers.addAll(signers) + commands.add(Command(commandData, signers)) + } + + override fun verifies(): EnforceVerifyOrFail { + val resolvedTransaction = ledgerInterpreter.resolveWireTransaction(toWireTransaction()) + resolvedTransaction.verify() + return EnforceVerifyOrFail.Token + } + + override fun failsWith(expectedMessage: String?): EnforceVerifyOrFail { + val exceptionThrown = try { + this.verifies() + false + } catch (exception: Exception) { + if (expectedMessage != null) { + val exceptionMessage = exception.message + if (exceptionMessage == null) { + throw AssertionError( + "Expected exception containing '$expectedMessage' but raised exception had no message" + ) + } else if (!exceptionMessage.toLowerCase().contains(expectedMessage.toLowerCase())) { + throw AssertionError( + "Expected exception containing '$expectedMessage' but raised exception was '$exception'" + ) + } + } + true + } + + if (!exceptionThrown) { + throw AssertionError("Expected exception but didn't get one") + } + + return EnforceVerifyOrFail.Token + } + + override fun tweak( + dsl: TransactionDSL< + EnforceVerifyOrFail, + TransactionDSLInterpreter + >.() -> EnforceVerifyOrFail + ) = dsl(TransactionDSL(copy())) +} + +class AttachmentResolutionException(attachmentId: SecureHash) : + Exception("Attachment with id $attachmentId not found") + +data class TestLedgerDSLInterpreter private constructor ( + private val identityService: IdentityService, + private val storageService: StorageService, + internal val labelToOutputStateAndRefs: HashMap> = HashMap(), + private val transactionWithLocations: HashMap = HashMap(), + private val nonVerifiedTransactionWithLocations: HashMap = HashMap() +) : LedgerDSLInterpreter { + + val wireTransactions: List get() = transactionWithLocations.values.map { it.transaction } + + // We specify [labelToOutputStateAndRefs] just so that Kotlin picks the primary constructor instead of cycling + constructor(identityService: IdentityService, storageService: StorageService) : this( + identityService, storageService, labelToOutputStateAndRefs = HashMap() + ) + + companion object { + private fun getCallerLocation(offset: Int): String { + val stackTraceElement = Thread.currentThread().stackTrace[3 + offset] + return stackTraceElement.toString() + } + } + + internal data class WireTransactionWithLocation( + val label: String?, + val transaction: WireTransaction, + val location: String + ) + class VerifiesFailed(transactionLocation: String, cause: Throwable) : + Exception("Transaction defined at ($transactionLocation) didn't verify: $cause", cause) + class TypeMismatch(requested: Class<*>, actual: Class<*>) : + Exception("Actual type $actual is not a subtype of requested type $requested") + + internal fun copy(): TestLedgerDSLInterpreter = + TestLedgerDSLInterpreter( + identityService, + storageService, + labelToOutputStateAndRefs = HashMap(labelToOutputStateAndRefs), + transactionWithLocations = HashMap(transactionWithLocations), + nonVerifiedTransactionWithLocations = HashMap(nonVerifiedTransactionWithLocations) + ) + + internal fun resolveWireTransaction(wireTransaction: WireTransaction): TransactionForVerification { + return wireTransaction.run { + val authenticatedCommands = commands.map { + AuthenticatedObject(it.signers, it.signers.mapNotNull { identityService.partyFromKey(it) }, it.value) + } + val resolvedInputStates = inputs.map { resolveStateRef(it) } + val resolvedAttachments = attachments.map { resolveAttachment(it) } + TransactionForVerification( + inputs = resolvedInputStates, + outputs = outputs, + commands = authenticatedCommands, + origHash = wireTransaction.serialized.hash, + attachments = resolvedAttachments, + signers = signers.toList(), + type = type + ) + + } + } + + internal inline fun resolveStateRef(stateRef: StateRef): TransactionState { + val transactionWithLocation = + transactionWithLocations[stateRef.txhash] ?: + nonVerifiedTransactionWithLocations[stateRef.txhash] ?: + throw TransactionResolutionException(stateRef.txhash) + val output = transactionWithLocation.transaction.outputs[stateRef.index] + return if (S::class.java.isAssignableFrom(output.data.javaClass)) @Suppress("UNCHECKED_CAST") { + output as TransactionState + } else { + throw TypeMismatch(requested = S::class.java, actual = output.data.javaClass) + } + } + + internal fun resolveAttachment(attachmentId: SecureHash): Attachment = + storageService.attachments.openAttachment(attachmentId) ?: throw AttachmentResolutionException(attachmentId) + + private fun interpretTransactionDsl( + dsl: TransactionDSL.() -> Return + ): TestTransactionDSLInterpreter { + val transactionInterpreter = TestTransactionDSLInterpreter(this) + dsl(TransactionDSL(transactionInterpreter)) + return transactionInterpreter + } + + fun toTransactionGroup(): TransactionGroup { + val ledgerTransactions = transactionWithLocations.map { + it.value.transaction.toLedgerTransaction(identityService, storageService.attachments) + } + val nonVerifiedLedgerTransactions = nonVerifiedTransactionWithLocations.map { + it.value.transaction.toLedgerTransaction(identityService, storageService.attachments) + } + return TransactionGroup(ledgerTransactions.toSet(), nonVerifiedLedgerTransactions.toSet()) + } + + fun transactionName(transactionHash: SecureHash): String? { + val transactionWithLocation = transactionWithLocations[transactionHash] + return if (transactionWithLocation != null) { + transactionWithLocation.label ?: "TX[${transactionWithLocation.location}]" + } else { + null + } + } + + fun outputToLabel(state: ContractState): String? = + labelToOutputStateAndRefs.filter { it.value.state.data == state }.keys.firstOrNull() + + private fun recordTransactionWithTransactionMap( + transactionLabel: String?, + dsl: TransactionDSL.() -> R, + transactionMap: HashMap = HashMap() + ): WireTransaction { + val transactionLocation = getCallerLocation(3) + val transactionInterpreter = interpretTransactionDsl(dsl) + // Create the WireTransaction + val wireTransaction = transactionInterpreter.toWireTransaction() + // Record the output states + transactionInterpreter.outputStates.forEachIndexed { index, labeledOutput -> + if (labeledOutput.label != null) { + labelToOutputStateAndRefs[labeledOutput.label] = wireTransaction.outRef(index) + } + } + + transactionMap[wireTransaction.serialized.hash] = + WireTransactionWithLocation(transactionLabel, wireTransaction, transactionLocation) + + return wireTransaction + } + + override fun transaction( + transactionLabel: String?, + dsl: TransactionDSL.() -> EnforceVerifyOrFail + ) = recordTransactionWithTransactionMap(transactionLabel, dsl, transactionWithLocations) + + override fun unverifiedTransaction( + transactionLabel: String?, + dsl: TransactionDSL.() -> Unit + ) = recordTransactionWithTransactionMap(transactionLabel, dsl, nonVerifiedTransactionWithLocations) + + override fun tweak( + dsl: LedgerDSL>.() -> Unit) = + dsl(LedgerDSL(copy())) + + override fun attachment(attachment: InputStream): SecureHash { + return storageService.attachments.importAttachment(attachment) + } + + override fun verifies() { + val transactionGroup = toTransactionGroup() + try { + transactionGroup.verify() + } catch (exception: TransactionVerificationException) { + throw VerifiesFailed(transactionWithLocations[exception.tx.origHash]?.location ?: "", exception) + } + } + + override fun retrieveOutputStateAndRef(clazz: Class, label: String): StateAndRef { + val stateAndRef = labelToOutputStateAndRefs[label] + if (stateAndRef == null) { + throw IllegalArgumentException("State with label '$label' was not found") + } else if (!clazz.isAssignableFrom(stateAndRef.state.data.javaClass)) { + throw TypeMismatch(requested = clazz, actual = stateAndRef.state.data.javaClass) + } else { + @Suppress("UNCHECKED_CAST") + return stateAndRef as StateAndRef + } + } +} + +fun signAll(transactionsToSign: List, extraKeys: Array) = transactionsToSign.map { wtx -> + val allPubKeys = wtx.signers.toMutableSet() + val bits = wtx.serialize() + require(bits == wtx.serialized) + val signatures = ArrayList() + for (key in ALL_TEST_KEYS + extraKeys) { + if (allPubKeys.contains(key.public)) { + signatures += key.signWithECDSA(bits) + allPubKeys -= key.public + } + } + SignedTransaction(bits, signatures) +} + +fun LedgerDSL.signAll( + transactionsToSign: List = this.interpreter.wireTransactions, vararg extraKeys: KeyPair) = + signAll(transactionsToSign, extraKeys) diff --git a/core/src/main/kotlin/com/r3corda/core/testing/TestUtils.kt b/core/src/main/kotlin/com/r3corda/core/testing/TestUtils.kt index d5148803e6..ad3557ae39 100644 --- a/core/src/main/kotlin/com/r3corda/core/testing/TestUtils.kt +++ b/core/src/main/kotlin/com/r3corda/core/testing/TestUtils.kt @@ -7,18 +7,13 @@ import com.google.common.net.HostAndPort import com.r3corda.core.contracts.* import com.r3corda.core.crypto.* import com.r3corda.core.node.services.IdentityService +import com.r3corda.core.node.services.StorageService import com.r3corda.core.node.services.testing.MockIdentityService import com.r3corda.core.node.services.testing.MockStorageService -import com.r3corda.core.seconds -import com.r3corda.core.serialization.serialize import java.net.ServerSocket import java.security.KeyPair import java.security.PublicKey import java.time.Instant -import java.util.* -import kotlin.test.assertEquals -import kotlin.test.assertFailsWith -import kotlin.test.fail /** If an exception is thrown by the body, rethrows the root cause exception. */ inline fun rootCauseExceptions(body: () -> R): R { @@ -95,9 +90,23 @@ object JavaTestHelpers { @JvmStatic fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0) - @JvmStatic fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure { - return body(TransactionForTest()) + @JvmStatic @JvmOverloads fun ledger( + identityService: IdentityService = MOCK_IDENTITY_SERVICE, + storageService: StorageService = MockStorageService(), + dsl: LedgerDSL.() -> Unit + ): LedgerDSL { + val ledgerDsl = LedgerDSL(TestLedgerDSLInterpreter(identityService, storageService)) + dsl(ledgerDsl) + return ledgerDsl } + + @JvmStatic @JvmOverloads fun transaction( + transactionLabel: String? = null, + dsl: TransactionDSL< + EnforceVerifyOrFail, + TransactionDSLInterpreter + >.() -> EnforceVerifyOrFail + ) = ledger { transaction(transactionLabel, dsl) } } val TEST_TX_TIME = JavaTestHelpers.TEST_TX_TIME @@ -124,27 +133,6 @@ val MOCK_IDENTITY_SERVICE = JavaTestHelpers.MOCK_IDENTITY_SERVICE fun generateStateRef() = JavaTestHelpers.generateStateRef() -fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure) = JavaTestHelpers.transaction(body) - -//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// -// Defines a simple DSL for building pseudo-transactions (not the same as the wire protocol) for testing purposes. -// -// Define a transaction like this: -// -// transaction { -// input { someExpression } -// output { someExpression } -// arg { someExpression } -// -// tweak { -// ... same thing but works with a copy of the parent, can add inputs/outputs/args just within this scope. -// } -// -// contract.accepts() -> should pass -// contract `fails requirement` "some substring of the error message" -// } -// class LabeledOutput(val label: String?, val state: TransactionState<*>) { override fun toString() = state.toString() + (if (label != null) " ($label)" else "") override fun equals(other: Any?) = other is LabeledOutput && state.equals(other.state) @@ -153,298 +141,3 @@ class LabeledOutput(val label: String?, val state: TransactionState<*>) { infix fun TransactionState<*>.label(label: String) = LabeledOutput(label, this) -abstract class AbstractTransactionForTest { - protected val attachments = ArrayList() - protected val outStates = ArrayList() - protected val commands = ArrayList() - protected val signers = LinkedHashSet() - protected val type = TransactionType.General() - - @JvmOverloads - open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, TransactionState(s(), DUMMY_NOTARY)).apply { outStates.add(this) } - @JvmOverloads - open fun output(label: String? = null, s: ContractState) = output(label) { s } - - protected fun commandsToAuthenticatedObjects(): List> { - return commands.map { AuthenticatedObject(it.signers, it.signers.mapNotNull { MOCK_IDENTITY_SERVICE.partyFromKey(it) }, it.value) } - } - - fun attachment(attachmentID: SecureHash) { - attachments.add(attachmentID) - } - - fun arg(vararg keys: PublicKey, c: () -> CommandData) { - val keysList = listOf(*keys) - addCommand(Command(c(), keysList)) - } - fun arg(key: PublicKey, c: CommandData) = arg(key) { c } - - fun timestamp(time: Instant) { - val data = TimestampCommand(time, 30.seconds) - timestamp(data) - } - - fun timestamp(data: TimestampCommand) { - addCommand(Command(data, DUMMY_NOTARY.owningKey)) - } - - fun addCommand(cmd: Command) { - signers.addAll(cmd.signers) - commands.add(cmd) - } - - // Forbid patterns like: transaction { ... transaction { ... } } - @Deprecated("Cannot nest transactions, use tweak", level = DeprecationLevel.ERROR) - fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure) { - } -} - -/** If you jumped here from a compiler error make sure the last line of your test tests for a transaction accept or fail - * This is a dummy type that can only be instantiated by functions in this module. This way we can ensure that all tests - * will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of - * the triggered diagnostic - */ -sealed class LastLineShouldTestForAcceptOrFailure { - internal object Token: LastLineShouldTestForAcceptOrFailure() -} - -// Corresponds to the args to Contract.verify -// Note on defaults: try to avoid Kotlin defaults as they don't work from Java. Instead define overloads -open class TransactionForTest : AbstractTransactionForTest() { - private val inStates = arrayListOf>() - - fun input(s: () -> ContractState) { - signers.add(DUMMY_NOTARY.owningKey) - inStates.add(TransactionState(s(), DUMMY_NOTARY)) - } - fun input(s: ContractState) = input { s } - - protected fun runCommandsAndVerify(time: Instant) { - val cmds = commandsToAuthenticatedObjects() - val tx = TransactionForVerification(inStates, outStates.map { it.state }, emptyList(), cmds, SecureHash.Companion.randomSHA256(), signers.toList(), type) - tx.verify() - } - - @JvmOverloads - fun accepts(time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure { - runCommandsAndVerify(time) - return LastLineShouldTestForAcceptOrFailure.Token - } - - @JvmOverloads - fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure { - val r = try { - runCommandsAndVerify(time) - false - } catch (e: Exception) { - val m = e.message - if (m == null) - fail("Threw exception without a message") - else - if (withMessage != null && !m.toLowerCase().contains(withMessage.toLowerCase())) throw AssertionError("Error was actually: $m", e) - true - } - if (!r) throw AssertionError("Expected exception but didn't get one") - return LastLineShouldTestForAcceptOrFailure.Token - } - - /** - * Used to confirm that the test, when (implicitly) run against the .verify() method, fails with the text of the message - */ - infix fun `fails requirement`(msg: String): LastLineShouldTestForAcceptOrFailure = rejects(msg) - fun failsRequirement(msg: String) = this.`fails requirement`(msg) - - // Use this to create transactions where the output of this transaction is automatically used as an input of - // the next. - fun chain(vararg outputLabels: String, body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): TransactionForTest { - val states = outStates.mapNotNull { - val l = it.label - if (l != null && outputLabels.contains(l)) - it.state - else - null - } - val tx = TransactionForTest() - tx.inStates.addAll(states) - tx.body() - return tx - } - - // Allow customisation of partial transactions. - fun tweak(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure { - val tx = TransactionForTest() - tx.inStates.addAll(inStates) - tx.outStates.addAll(outStates) - tx.commands.addAll(commands) - - tx.signers.addAll(tx.inStates.map { it.notary.owningKey }) - tx.signers.addAll(commands.flatMap { it.signers }) - return tx.body() - } - - override fun toString(): String { - return """transaction { - inputs: $inStates - outputs: $outStates - commands $commands - }""" - } - - override fun equals(other: Any?) = this === other || (other is TransactionForTest && inStates == other.inStates && outStates == other.outStates && commands == other.commands) - - override fun hashCode(): Int { - var result = inStates.hashCode() - result += 31 * result + outStates.hashCode() - result += 31 * result + commands.hashCode() - return result - } -} - -class TransactionGroupDSL(private val stateType: Class) { - open inner class WireTransactionDSL : AbstractTransactionForTest() { - private val inStates = ArrayList() - - fun input(label: String) { - val notaryKey = label.output.notary.owningKey - signers.add(notaryKey) - inStates.add(label.outputRef) - } - - fun toWireTransaction() = WireTransaction(inStates, attachments, outStates.map { it.state }, commands, signers.toList(), type) - } - - val String.output: TransactionState - get() = labelToOutputs[this] ?: throw IllegalArgumentException("State with label '$this' was not found") - val String.outputRef: StateRef get() = labelToRefs[this] ?: throw IllegalArgumentException("Unknown label \"$this\"") - - fun lookup(label: String): StateAndRef { - val output = label.output - val newOutput = TransactionState(output.data as C, output.notary) - return StateAndRef(newOutput, label.outputRef) - } - - private inner class InternalWireTransactionDSL : WireTransactionDSL() { - fun finaliseAndInsertLabels(): WireTransaction { - val wtx = toWireTransaction() - for ((index, labelledState) in outStates.withIndex()) { - if (labelledState.label != null) { - labelToRefs[labelledState.label] = StateRef(wtx.id, index) - if (stateType.isInstance(labelledState.state.data)) { - labelToOutputs[labelledState.label] = labelledState.state as TransactionState - } - outputsToLabels[labelledState.state] = labelledState.label - } - } - return wtx - } - } - - private val rootTxns = ArrayList() - private val labelToRefs = HashMap() - private val labelToOutputs = HashMap>() - private val outputsToLabels = HashMap, String>() - - fun labelForState(output: TransactionState<*>): String? = outputsToLabels[output] - - inner class Roots { - fun transaction(vararg outputStates: LabeledOutput): Roots { - val outs = outputStates.map { it.state } - val wtx = WireTransaction(emptyList(), emptyList(), outs, emptyList(), emptyList(), TransactionType.General()) - for ((index, state) in outputStates.withIndex()) { - val label = state.label!! - labelToRefs[label] = StateRef(wtx.id, index) - outputsToLabels[state.state] = label - labelToOutputs[label] = state.state as TransactionState - } - rootTxns.add(wtx) - return this - } - - /** - * Note: Don't delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place - */ - @Deprecated("Does not nest ", level = DeprecationLevel.ERROR) - fun roots(body: Roots.() -> Unit) { - } - - /** - * Note: Don't delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place - */ - @Deprecated("Use the vararg form of transaction inside roots", level = DeprecationLevel.ERROR) - fun transaction(body: WireTransactionDSL.() -> Unit) { - } - } - - fun roots(body: Roots.() -> Unit) = Roots().apply { body() } - - val txns = ArrayList() - private val txnToLabelMap = HashMap() - - @JvmOverloads - fun transaction(label: String? = null, body: WireTransactionDSL.() -> Unit): WireTransaction { - val forTest = InternalWireTransactionDSL() - forTest.body() - val wtx = forTest.finaliseAndInsertLabels() - txns.add(wtx) - if (label != null) - txnToLabelMap[wtx.id] = label - return wtx - } - - fun labelForTransaction(tx: WireTransaction): String? = txnToLabelMap[tx.id] - fun labelForTransaction(tx: LedgerTransaction): String? = txnToLabelMap[tx.id] - - /** - * Note: Don't delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place - */ - @Deprecated("Does not nest ", level = DeprecationLevel.ERROR) - fun transactionGroup(body: TransactionGroupDSL.() -> Unit) { - } - - fun toTransactionGroup() = TransactionGroup( - txns.map { it.toLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) }.toSet(), - rootTxns.map { it.toLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) }.toSet() - ) - - class Failed(val index: Int, cause: Throwable) : Exception("Transaction $index didn't verify", cause) - - fun verify() { - val group = toTransactionGroup() - try { - group.verify() - } catch (e: TransactionVerificationException) { - // Let the developer know the index of the transaction that failed. - val wtx: WireTransaction = txns.find { it.id == e.tx.origHash }!! - throw Failed(txns.indexOf(wtx) + 1, e) - } - } - - fun expectFailureOfTx(index: Int, message: String): Exception { - val e = assertFailsWith(Failed::class) { - verify() - } - assertEquals(index, e.index) - if (!(e.cause?.message ?: "") .contains(message)) - throw AssertionError("Exception should have said '$message' but was actually: ${e.cause?.message}", e.cause) - return e - } - - fun signAll(txnsToSign: List = txns, vararg extraKeys: KeyPair): List { - return txnsToSign.map { wtx -> - val allPubKeys = wtx.signers.toMutableSet() - val bits = wtx.serialize() - require(bits == wtx.serialized) - val sigs = ArrayList() - for (key in ALL_TEST_KEYS + extraKeys) { - if (allPubKeys.contains(key.public)) { - sigs += key.signWithECDSA(bits) - allPubKeys -= key.public - } - } - SignedTransaction(bits, sigs) - } - } -} - -inline fun transactionGroupFor(body: TransactionGroupDSL.() -> Unit) = TransactionGroupDSL(T::class.java).apply { this.body() } -fun transactionGroup(body: TransactionGroupDSL.() -> Unit) = TransactionGroupDSL(ContractState::class.java).apply { this.body() } diff --git a/core/src/main/kotlin/com/r3corda/core/testing/TransactionDSLInterpreter.kt b/core/src/main/kotlin/com/r3corda/core/testing/TransactionDSLInterpreter.kt new file mode 100644 index 0000000000..f8421a8326 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/testing/TransactionDSLInterpreter.kt @@ -0,0 +1,88 @@ +package com.r3corda.core.testing + +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.Party +import com.r3corda.core.crypto.SecureHash +import com.r3corda.core.seconds +import java.security.PublicKey +import java.time.Instant + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// +// Defines a simple DSL for building pseudo-transactions (not the same as the wire protocol) for testing purposes. +// +// Define a transaction like this: +// +// ledger { +// transaction { +// input { someExpression } +// output { someExpression } +// command { someExpression } +// +// tweak { +// ... same thing but works with a copy of the parent, can add inputs/outputs/commands just within this scope. +// } +// +// contract.verifies() -> verify() should pass +// contract `fails with` "some substring of the error message" +// } +// } +// + +/** + * The [TransactionDSLInterpreter] defines the interface DSL interpreters should satisfy. No + * overloading/default valuing should be done here, only the basic functions that are required to implement everything. + * Same goes for functions requiring reflection e.g. [OutputStateLookup.retrieveOutputStateAndRef] + * Put convenience functions in [TransactionDSL] instead. There are some cases where the overloads would clash with the + * Interpreter interface, in these cases define a "backing" function in the interface instead (e.g. [_command]). + * + * This way the responsibility of providing a nice frontend DSL and the implementation(s) are separated. + */ +interface TransactionDSLInterpreter : OutputStateLookup { + val ledgerInterpreter: LedgerDSLInterpreter> + fun input(stateRef: StateRef) + fun _output(label: String?, notary: Party, contractState: ContractState) + fun attachment(attachmentId: SecureHash) + fun _command(signers: List, commandData: CommandData) + fun verifies(): R + fun failsWith(expectedMessage: String?): R + fun tweak( + dsl: TransactionDSL>.() -> R + ): R +} + +class TransactionDSL> (val interpreter: T) : + TransactionDSLInterpreter by interpreter { + + fun input(stateLabel: String) = input(retrieveOutputStateAndRef(ContractState::class.java, stateLabel).ref) + /** + * Adds the passed in state as a non-verified transaction output to the ledger and adds that as an input. + */ + fun input(state: ContractState) { + val transaction = ledgerInterpreter.unverifiedTransaction(null) { + output { state } + } + input(transaction.outRef(0).ref) + } + fun input(stateClosure: () -> ContractState) = input(stateClosure()) + + @JvmOverloads + fun output(label: String? = null, notary: Party = DUMMY_NOTARY, contractStateClosure: () -> ContractState) = + _output(label, notary, contractStateClosure()) + @JvmOverloads + fun output(label: String? = null, contractState: ContractState) = + _output(label, DUMMY_NOTARY, contractState) + + fun command(vararg signers: PublicKey, commandDataClosure: () -> CommandData) = + _command(listOf(*signers), commandDataClosure()) + fun command(signer: PublicKey, commandData: CommandData) = _command(listOf(signer), commandData) + + @JvmOverloads + fun timestamp(time: Instant, notary: PublicKey = DUMMY_NOTARY.owningKey) = + timestamp(TimestampCommand(time, 30.seconds), notary) + @JvmOverloads + fun timestamp(data: TimestampCommand, notary: PublicKey = DUMMY_NOTARY.owningKey) = command(notary, data) + + fun fails() = failsWith(null) + infix fun `fails with`(msg: String) = failsWith(msg) +} diff --git a/core/src/main/kotlin/com/r3corda/core/utilities/Emoji.kt b/core/src/main/kotlin/com/r3corda/core/utilities/Emoji.kt index 98fb29ad68..864cb4c044 100644 --- a/core/src/main/kotlin/com/r3corda/core/utilities/Emoji.kt +++ b/core/src/main/kotlin/com/r3corda/core/utilities/Emoji.kt @@ -4,7 +4,7 @@ package com.r3corda.core.utilities * A simple wrapper class that contains icons and support for printing them only when we're connected to a terminal. */ object Emoji { - val hasEmojiTerminal by lazy { System.getenv("TERM") != null && System.getenv("LANG").contains("UTF-8") } + val hasEmojiTerminal by lazy { System.getenv("TERM") != null && (System.getenv("LANG")?.contains("UTF-8") == true) } const val CODE_DIAMOND = "\ud83d\udd37" const val CODE_BAG_OF_CASH = "\ud83d\udcb0" diff --git a/core/src/main/kotlin/com/r3corda/core/utilities/OracleUtils.kt b/core/src/main/kotlin/com/r3corda/core/utilities/OracleUtils.kt new file mode 100644 index 0000000000..6414b29272 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/core/utilities/OracleUtils.kt @@ -0,0 +1,19 @@ +package com.r3corda.core.utilities + +import java.time.* + +/** + * This whole file exists as short cuts to get demos working. In reality we'd have static data and/or rules engine + * defining things like this. It currently resides in the core module because it needs to be visible to the IRS + * contract. + */ +// We at some future point may implement more than just this constant announcement window and thus use the params. +@Suppress("UNUSED_PARAMETER") +fun suggestInterestRateAnnouncementTimeWindow(index: String, source: String, date: LocalDate): TimeWindow { + // TODO: we would ordinarily convert clock to same time zone as the index/source would announce in + // and suggest an announcement time for the interest rate + // Here we apply a blanket announcement time of 11:45 London irrespective of source or index + val time = LocalTime.of(11, 45) + val zoneId = ZoneId.of("Europe/London") + return TimeWindow(ZonedDateTime.of(date, time, zoneId).toInstant(), Duration.ofHours(24)) +} diff --git a/core/src/main/kotlin/com/r3corda/protocols/AbstractRequestMessage.kt b/core/src/main/kotlin/com/r3corda/protocols/AbstractRequestMessage.kt deleted file mode 100644 index 414df561f5..0000000000 --- a/core/src/main/kotlin/com/r3corda/protocols/AbstractRequestMessage.kt +++ /dev/null @@ -1,9 +0,0 @@ -package com.r3corda.protocols - -import com.r3corda.core.messaging.MessageRecipients - -/** - * Abstract superclass for request messages sent to services, which includes common - * fields such as replyTo and replyToTopic. - */ -abstract class AbstractRequestMessage(val replyTo: MessageRecipients, val sessionID: Long?) \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/protocols/FetchAttachmentsProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/FetchAttachmentsProtocol.kt index dd19927281..0e1c579b2b 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/FetchAttachmentsProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/FetchAttachmentsProtocol.kt @@ -1,9 +1,9 @@ package com.r3corda.protocols import com.r3corda.core.contracts.Attachment +import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash import com.r3corda.core.crypto.sha256 -import com.r3corda.core.messaging.SingleMessageRecipient import java.io.ByteArrayInputStream import java.io.InputStream @@ -12,14 +12,15 @@ import java.io.InputStream * attachments are saved to local storage automatically. */ class FetchAttachmentsProtocol(requests: Set, - otherSide: SingleMessageRecipient) : FetchDataProtocol(requests, otherSide) { + otherSide: Party) : FetchDataProtocol(requests, otherSide) { + companion object { const val TOPIC = "platform.fetch.attachment" } - override fun load(txid: SecureHash): Attachment? = serviceHub.storageService.attachments.openAttachment(txid) + override val topic: String get() = TOPIC - override val queryTopic: String = TOPIC + override fun load(txid: SecureHash): Attachment? = serviceHub.storageService.attachments.openAttachment(txid) override fun convert(wire: ByteArray): Attachment { return object : Attachment { diff --git a/core/src/main/kotlin/com/r3corda/protocols/FetchDataProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/FetchDataProtocol.kt index 2530269bd9..f72aafbeb9 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/FetchDataProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/FetchDataProtocol.kt @@ -2,8 +2,8 @@ package com.r3corda.protocols import co.paralleluniverse.fibers.Suspendable import com.r3corda.core.contracts.NamedByHash +import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.random63BitValue import com.r3corda.core.utilities.UntrustworthyData @@ -27,17 +27,15 @@ import java.util.* */ abstract class FetchDataProtocol( protected val requests: Set, - protected val otherSide: SingleMessageRecipient) : ProtocolLogic>() { + protected val otherSide: Party) : ProtocolLogic>() { open class BadAnswer : Exception() class HashNotFound(val requested: SecureHash) : BadAnswer() class DownloadedVsRequestedDataMismatch(val requested: SecureHash, val got: SecureHash) : BadAnswer() - class Request(val hashes: List, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + data class Request(val hashes: List, override val replyToParty: Party, override val sessionID: Long) : PartyRequestMessage data class Result(val fromDisk: List, val downloaded: List) - protected abstract val queryTopic: String - @Suspendable override fun call(): Result { // Load the items we have from disk and figure out which we're missing. @@ -49,9 +47,9 @@ abstract class FetchDataProtocol( logger.trace("Requesting ${toFetch.size} dependency(s) for verification") val sid = random63BitValue() - val fetchReq = Request(toFetch, serviceHub.networkService.myAddress, sid) + val fetchReq = Request(toFetch, serviceHub.storageService.myLegalIdentity, sid) // TODO: Support "large message" response streaming so response sizes are not limited by RAM. - val maybeItems = sendAndReceive>(queryTopic, otherSide, 0, sid, fetchReq) + val maybeItems = sendAndReceive>(otherSide, 0, sid, fetchReq) // Check for a buggy/malicious peer answering with something that we didn't ask for. val downloaded = validateFetchResponse(maybeItems, toFetch) maybeWriteToDisk(downloaded) diff --git a/core/src/main/kotlin/com/r3corda/protocols/FetchTransactionsProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/FetchTransactionsProtocol.kt index 032fa9b583..69d7535ea7 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/FetchTransactionsProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/FetchTransactionsProtocol.kt @@ -1,8 +1,8 @@ package com.r3corda.protocols import com.r3corda.core.contracts.SignedTransaction +import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash -import com.r3corda.core.messaging.SingleMessageRecipient /** * Given a set of tx hashes (IDs), either loads them from local disk or asks the remote peer to provide them. @@ -12,12 +12,14 @@ import com.r3corda.core.messaging.SingleMessageRecipient * results in a [FetchDataProtocol.HashNotFound] exception. Note that returned transactions are not inserted into * the database, because it's up to the caller to actually verify the transactions are valid. */ -class FetchTransactionsProtocol(requests: Set, otherSide: SingleMessageRecipient) : +class FetchTransactionsProtocol(requests: Set, otherSide: Party) : FetchDataProtocol(requests, otherSide) { + companion object { const val TOPIC = "platform.fetch.tx" } + override val topic: String get() = TOPIC + override fun load(txid: SecureHash): SignedTransaction? = serviceHub.storageService.validatedTransactions.getTransaction(txid) - override val queryTopic: String = TOPIC } \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt index f7e50cf3d4..2157ca8dbf 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/NotaryProtocol.kt @@ -9,8 +9,6 @@ import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SignedData import com.r3corda.core.crypto.signWithECDSA import com.r3corda.core.messaging.Ack -import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.services.TimestampChecker import com.r3corda.core.node.services.UniquenessException import com.r3corda.core.node.services.UniquenessProvider @@ -24,8 +22,8 @@ import com.r3corda.core.utilities.UntrustworthyData import java.security.PublicKey object NotaryProtocol { - val TOPIC = "platform.notary.request" - val TOPIC_INITIATE = "platform.notary.initiate" + + val TOPIC = "platform.notary" /** * A protocol to be used for obtaining a signature from a [NotaryService] ascertaining the transaction @@ -36,6 +34,7 @@ object NotaryProtocol { */ class Client(private val stx: SignedTransaction, override val progressTracker: ProgressTracker = Client.tracker()) : ProtocolLogic() { + companion object { object REQUESTING : ProgressTracker.Step("Requesting signature by Notary service") @@ -45,21 +44,23 @@ object NotaryProtocol { fun tracker() = ProgressTracker(REQUESTING, VALIDATING) } - lateinit var notaryNode: NodeInfo + override val topic: String get() = TOPIC + + lateinit var notaryParty: Party @Suspendable override fun call(): DigitalSignature.LegallyIdentifiable { progressTracker.currentStep = REQUESTING - notaryNode = findNotaryNode() + notaryParty = findNotaryParty() val sendSessionID = random63BitValue() val receiveSessionID = random63BitValue() - val handshake = Handshake(serviceHub.networkService.myAddress, sendSessionID, receiveSessionID) - sendAndReceive(TOPIC_INITIATE, notaryNode.address, 0, receiveSessionID, handshake) + val handshake = Handshake(serviceHub.storageService.myLegalIdentity, sendSessionID, receiveSessionID) + sendAndReceive(notaryParty, 0, receiveSessionID, handshake) val request = SignRequest(stx, serviceHub.storageService.myLegalIdentity) - val response = sendAndReceive(TOPIC, notaryNode.address, sendSessionID, receiveSessionID, request) + val response = sendAndReceive(notaryParty, sendSessionID, receiveSessionID, request) val notaryResult = validateResponse(response) return notaryResult.sig ?: throw NotaryException(notaryResult.error!!) @@ -72,17 +73,17 @@ object NotaryProtocol { if (it.sig != null) validateSignature(it.sig, stx.txBits) else if (it.error is NotaryError.Conflict) it.error.conflict.verified() else if (it.error == null || it.error !is NotaryError) - throw IllegalStateException("Received invalid result from Notary service '${notaryNode.identity}'") + throw IllegalStateException("Received invalid result from Notary service '$notaryParty'") return it } } private fun validateSignature(sig: DigitalSignature.LegallyIdentifiable, data: SerializedBytes) { - check(sig.signer == notaryNode.identity) { "Notary result not signed by the correct service" } + check(sig.signer == notaryParty) { "Notary result not signed by the correct service" } sig.verifyWithECDSA(data) } - private fun findNotaryNode(): NodeInfo { + private fun findNotaryParty(): Party { var maybeNotaryKey: PublicKey? = null val wtx = stx.tx @@ -97,8 +98,8 @@ object NotaryProtocol { } val notaryKey = maybeNotaryKey ?: throw IllegalStateException("Transaction does not specify a Notary") - val notaryNode = serviceHub.networkMapCache.getNodeByPublicKey(notaryKey) - return notaryNode ?: throw IllegalStateException("No Notary node can be found with the specified public key") + val notaryParty = serviceHub.networkMapCache.getNodeByPublicKey(notaryKey)?.identity + return notaryParty ?: throw IllegalStateException("No Notary node can be found with the specified public key") } } @@ -110,32 +111,31 @@ object NotaryProtocol { * * TODO: the notary service should only be able to see timestamp commands and inputs */ - open class Service(val otherSide: SingleMessageRecipient, + open class Service(val otherSide: Party, val sendSessionID: Long, val receiveSessionID: Long, val timestampChecker: TimestampChecker, val uniquenessProvider: UniquenessProvider) : ProtocolLogic() { + + override val topic: String get() = TOPIC + @Suspendable override fun call() { - val request = receive(TOPIC, receiveSessionID).validate { it } - val stx = request.tx + val (stx, reqIdentity) = receive(receiveSessionID).validate { it } val wtx = stx.tx - val reqIdentity = request.callerIdentity - val result: Result - try { + val result = try { validateTimestamp(wtx) beforeCommit(stx, reqIdentity) commitInputStates(wtx, reqIdentity) val sig = sign(stx.txBits) - result = Result.noError(sig) - + Result.noError(sig) } catch(e: NotaryException) { - result = Result.withError(e.error) + Result.withError(e.error) } - send(TOPIC, otherSide, sendSessionID, result) + send(otherSide, sendSessionID, result) } private fun validateTimestamp(tx: WireTransaction) { @@ -180,14 +180,13 @@ object NotaryProtocol { } } - class Handshake( - replyTo: SingleMessageRecipient, + data class Handshake( + override val replyToParty: Party, val sendSessionID: Long, - sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + override val sessionID: Long) : PartyRequestMessage /** TODO: The caller must authenticate instead of just specifying its identity */ - class SignRequest(val tx: SignedTransaction, - val callerIdentity: Party) + data class SignRequest(val tx: SignedTransaction, val callerIdentity: Party) data class Result private constructor(val sig: DigitalSignature.LegallyIdentifiable?, val error: NotaryError?) { companion object { @@ -197,7 +196,7 @@ object NotaryProtocol { } interface Factory { - fun create(otherSide: SingleMessageRecipient, + fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, @@ -205,7 +204,7 @@ object NotaryProtocol { } object DefaultFactory : Factory { - override fun create(otherSide: SingleMessageRecipient, + override fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, diff --git a/core/src/main/kotlin/com/r3corda/protocols/RatesFixProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/RatesFixProtocol.kt index 62f0e020cc..d61ad3d968 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/RatesFixProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/RatesFixProtocol.kt @@ -1,17 +1,19 @@ package com.r3corda.protocols import co.paralleluniverse.fibers.Suspendable -import com.r3corda.core.* import com.r3corda.core.contracts.Fix import com.r3corda.core.contracts.FixOf import com.r3corda.core.contracts.TransactionBuilder import com.r3corda.core.contracts.WireTransaction import com.r3corda.core.crypto.DigitalSignature -import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.NodeInfo +import com.r3corda.core.crypto.Party import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.random63BitValue import com.r3corda.core.utilities.ProgressTracker +import com.r3corda.core.utilities.suggestInterestRateAnnouncementTimeWindow import java.math.BigDecimal +import java.time.Duration +import java.time.Instant import java.util.* // This code is unit tested in NodeInterestRates.kt @@ -25,15 +27,15 @@ import java.util.* * @throws FixOutOfRange if the returned fix was further away from the expected rate by the given amount. */ open class RatesFixProtocol(protected val tx: TransactionBuilder, - private val oracle: NodeInfo, + private val oracle: Party, private val fixOf: FixOf, private val expectedRate: BigDecimal, private val rateTolerance: BigDecimal, + private val timeOut: Duration, override val progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name)) : ProtocolLogic() { + companion object { val TOPIC = "platform.rates.interest.fix" - val TOPIC_SIGN = TOPIC + ".sign" - val TOPIC_QUERY = TOPIC + ".query" class QUERYING(val name: String) : ProgressTracker.Step("Querying oracle for $name interest rate") object WORKING : ProgressTracker.Step("Working with data returned by oracle") @@ -42,10 +44,12 @@ open class RatesFixProtocol(protected val tx: TransactionBuilder, fun tracker(fixName: String) = ProgressTracker(QUERYING(fixName), WORKING, SIGNING) } + override val topic: String get() = TOPIC + class FixOutOfRange(val byAmount: BigDecimal) : Exception() - class QueryRequest(val queries: List, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) - class SignRequest(val tx: WireTransaction, replyTo: SingleMessageRecipient, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + data class QueryRequest(val queries: List, override val replyToParty: Party, override val sessionID: Long, val deadline: Instant) : PartyRequestMessage + data class SignRequest(val tx: WireTransaction, override val replyToParty: Party, override val sessionID: Long) : PartyRequestMessage @Suspendable override fun call() { @@ -53,7 +57,7 @@ open class RatesFixProtocol(protected val tx: TransactionBuilder, val fix = query() progressTracker.currentStep = WORKING checkFixIsNearExpected(fix) - tx.addCommand(fix, oracle.identity.owningKey) + tx.addCommand(fix, oracle.owningKey) beforeSigning(fix) progressTracker.currentStep = SIGNING tx.addSignatureUnchecked(sign()) @@ -76,24 +80,26 @@ open class RatesFixProtocol(protected val tx: TransactionBuilder, } @Suspendable - fun sign(): DigitalSignature.LegallyIdentifiable { + private fun sign(): DigitalSignature.LegallyIdentifiable { val sessionID = random63BitValue() val wtx = tx.toWireTransaction() - val req = SignRequest(wtx, serviceHub.networkService.myAddress, sessionID) - val resp = sendAndReceive(TOPIC_SIGN, oracle.address, 0, sessionID, req) + val req = SignRequest(wtx, serviceHub.storageService.myLegalIdentity, sessionID) + val resp = sendAndReceive(oracle, 0, sessionID, req) return resp.validate { sig -> - check(sig.signer == oracle.identity) + check(sig.signer == oracle) tx.checkSignature(sig) sig } } @Suspendable - fun query(): Fix { + private fun query(): Fix { val sessionID = random63BitValue() - val req = QueryRequest(listOf(fixOf), serviceHub.networkService.myAddress, sessionID) - val resp = sendAndReceive>(TOPIC_QUERY, oracle.address, 0, sessionID, req) + val deadline = suggestInterestRateAnnouncementTimeWindow(fixOf.name, oracle.name, fixOf.forDay).end + val req = QueryRequest(listOf(fixOf), serviceHub.storageService.myLegalIdentity, sessionID, deadline) + // TODO: add deadline to receive + val resp = sendAndReceive>(oracle, 0, sessionID, req) return resp.validate { val fix = it.first() diff --git a/core/src/main/kotlin/com/r3corda/protocols/ResolveTransactionsProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/ResolveTransactionsProtocol.kt index 7639a0befb..2e09d2c348 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/ResolveTransactionsProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/ResolveTransactionsProtocol.kt @@ -2,8 +2,8 @@ package com.r3corda.protocols import co.paralleluniverse.fibers.Suspendable import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.protocols.ProtocolLogic import java.util.* @@ -21,7 +21,7 @@ import java.util.* * protocol is helpful when resolving and verifying a finished but partially signed transaction. */ class ResolveTransactionsProtocol(private val txHashes: Set, - private val otherSide: SingleMessageRecipient) : ProtocolLogic() { + private val otherSide: Party) : ProtocolLogic() { companion object { private fun dependencyIDs(wtx: WireTransaction) = wtx.inputs.map { it.txhash }.toSet() @@ -33,11 +33,11 @@ class ResolveTransactionsProtocol(private val txHashes: Set, private var stx: SignedTransaction? = null private var wtx: WireTransaction? = null - constructor(stx: SignedTransaction, otherSide: SingleMessageRecipient) : this(stx.tx, otherSide) { + constructor(stx: SignedTransaction, otherSide: Party) : this(stx.tx, otherSide) { this.stx = stx } - constructor(wtx: WireTransaction, otherSide: SingleMessageRecipient) : this(dependencyIDs(wtx), otherSide) { + constructor(wtx: WireTransaction, otherSide: Party) : this(dependencyIDs(wtx), otherSide) { this.wtx = wtx } @@ -70,6 +70,8 @@ class ResolveTransactionsProtocol(private val txHashes: Set, serviceHub.recordTransactions(downloadedSignedTxns) } + override val topic: String get() = throw UnsupportedOperationException() + @Suspendable private fun fetchDependenciesAndCheckSignatures(depsToCheck: Set, toVerify: HashSet, diff --git a/core/src/main/kotlin/com/r3corda/protocols/ServiceRequestMessage.kt b/core/src/main/kotlin/com/r3corda/protocols/ServiceRequestMessage.kt new file mode 100644 index 0000000000..3f878b3ce7 --- /dev/null +++ b/core/src/main/kotlin/com/r3corda/protocols/ServiceRequestMessage.kt @@ -0,0 +1,23 @@ +package com.r3corda.protocols + +import com.r3corda.core.crypto.Party +import com.r3corda.core.messaging.MessageRecipients +import com.r3corda.core.node.services.NetworkMapCache + +/** + * Abstract superclass for request messages sent to services, which includes common + * fields such as replyTo and sessionID. + */ +interface ServiceRequestMessage { + val sessionID: Long + fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients +} + +interface PartyRequestMessage : ServiceRequestMessage { + + val replyToParty: Party + + override fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients { + return networkMapCache.partyNodes.single { it.identity == replyToParty }.address + } +} \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt index 8e0bf8ecd9..b81cefa4f7 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/TwoPartyDealProtocol.kt @@ -1,11 +1,11 @@ package com.r3corda.protocols import co.paralleluniverse.fibers.Suspendable +import com.r3corda.core.TransientProperty import com.r3corda.core.contracts.* import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.signWithECDSA -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.NodeInfo import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.random63BitValue @@ -17,6 +17,7 @@ import java.math.BigDecimal import java.security.KeyPair import java.security.PublicKey import java.security.SignatureException +import java.time.Duration /** * Classes for manipulating a two party deal or agreement. @@ -25,9 +26,14 @@ import java.security.SignatureException * * TODO: Also, the term Deal is used here where we might prefer Agreement. * + * TODO: Consider whether we can merge this with [TwoPartyTradeProtocol] + * */ object TwoPartyDealProtocol { + val DEAL_TOPIC = "platform.deal" + /** This topic exists purely for [FixingSessionInitiation] to be sent from [FixingRoleDecider] to [FixingSessionInitiationHandler] */ + val FIX_INITIATE_TOPIC = "platform.fix.initiate" class DealMismatchException(val expectedDeal: ContractState, val actualDeal: ContractState) : Exception() { override fun toString() = "The submitted deal didn't match the expected: $expectedDeal vs $actualDeal" @@ -52,12 +58,7 @@ object TwoPartyDealProtocol { * There's a good chance we can push at least some of this logic down into core protocol logic * and helper methods etc. */ - abstract class Primary(val payload: U, - val otherSide: SingleMessageRecipient, - val otherSessionID: Long, - val myKeyPair: KeyPair, - val notaryNode: NodeInfo, - override val progressTracker: ProgressTracker = Primary.tracker()) : ProtocolLogic() { + abstract class Primary(override val progressTracker: ProgressTracker = Primary.tracker()) : ProtocolLogic() { companion object { object AWAITING_PROPOSAL : ProgressTracker.Step("Handshaking and awaiting transaction proposal") @@ -71,6 +72,14 @@ object TwoPartyDealProtocol { fun tracker() = ProgressTracker(AWAITING_PROPOSAL, VERIFYING, SIGNING, NOTARY, SENDING_SIGS, RECORDING, COPYING_TO_REGULATOR) } + override val topic: String get() = DEAL_TOPIC + + abstract val payload: U + abstract val notaryNode: NodeInfo + abstract val otherSide: Party + abstract val otherSessionID: Long + abstract val myKeyPair: KeyPair + @Suspendable fun getPartialTransaction(): UntrustworthyData { progressTracker.currentStep = AWAITING_PROPOSAL @@ -79,8 +88,7 @@ object TwoPartyDealProtocol { // Make the first message we'll send to kick off the protocol. val hello = Handshake(payload, myKeyPair.public, sessionID) - - val maybeSTX = sendAndReceive(DEAL_TOPIC, otherSide, otherSessionID, sessionID, hello) + val maybeSTX = sendAndReceive(otherSide, otherSessionID, sessionID, hello) return maybeSTX } @@ -143,12 +151,13 @@ object TwoPartyDealProtocol { logger.trace { "Deal stored" } + progressTracker.currentStep = COPYING_TO_REGULATOR val regulators = serviceHub.networkMapCache.regulators if (regulators.isNotEmpty()) { // Copy the transaction to every regulator in the network. This is obviously completely bogus, it's // just for demo purposes. for (regulator in regulators) { - send("regulator.all.seeing.eye", regulator.address, 0, fullySigned) + send(regulator.identity, 0, fullySigned) } } @@ -174,7 +183,7 @@ object TwoPartyDealProtocol { logger.trace { "Built finished transaction, sending back to other party!" } - send(DEAL_TOPIC, otherSide, otherSessionID, SignaturesFromPrimary(ourSignature, notarySignature)) + send(otherSide, otherSessionID, SignaturesFromPrimary(ourSignature, notarySignature)) return fullySigned } } @@ -186,10 +195,7 @@ object TwoPartyDealProtocol { * There's a good chance we can push at least some of this logic down into core protocol logic * and helper methods etc. */ - abstract class Secondary(val otherSide: SingleMessageRecipient, - val notary: Party, - val sessionID: Long, - override val progressTracker: ProgressTracker = Secondary.tracker()) : ProtocolLogic() { + abstract class Secondary(override val progressTracker: ProgressTracker = Secondary.tracker()) : ProtocolLogic() { companion object { object RECEIVING : ProgressTracker.Step("Waiting for deal info") @@ -201,6 +207,11 @@ object TwoPartyDealProtocol { fun tracker() = ProgressTracker(RECEIVING, VERIFYING, SIGNING, SWAPPING_SIGNATURES, RECORDING) } + override val topic: String get() = DEAL_TOPIC + + abstract val otherSide: Party + abstract val sessionID: Long + @Suspendable override fun call(): SignedTransaction { val handshake = receiveAndValidateHandshake() @@ -230,7 +241,7 @@ object TwoPartyDealProtocol { private fun receiveAndValidateHandshake(): Handshake { progressTracker.currentStep = RECEIVING // Wait for a trade request to come in on our pre-provided session ID. - val handshake = receive>(DEAL_TOPIC, sessionID) + val handshake = receive>(sessionID) progressTracker.currentStep = VERIFYING handshake.validate { @@ -241,11 +252,11 @@ object TwoPartyDealProtocol { @Suspendable private fun swapSignaturesWithPrimary(stx: SignedTransaction, theirSessionID: Long): SignaturesFromPrimary { progressTracker.currentStep = SWAPPING_SIGNATURES - logger.trace { "Sending partially signed transaction to seller" } + logger.trace { "Sending partially signed transaction to other party" } // TODO: Protect against the seller terminating here and leaving us in the lurch without the final tx. - return sendAndReceive(DEAL_TOPIC, otherSide, theirSessionID, sessionID, stx).validate { it } + return sendAndReceive(otherSide, theirSessionID, sessionID, stx).validate { it } } private fun signWithOurKeys(signingPubKeys: List, ptx: TransactionBuilder): SignedTransaction { @@ -271,45 +282,47 @@ object TwoPartyDealProtocol { /** * One side of the protocol for inserting a pre-agreed deal. */ - open class Instigator(otherSide: SingleMessageRecipient, - notaryNode: NodeInfo, - dealBeingOffered: T, - myKeyPair: KeyPair, - buyerSessionID: Long, - override val progressTracker: ProgressTracker = Primary.tracker()) : Primary(dealBeingOffered, otherSide, buyerSessionID, myKeyPair, notaryNode) + open class Instigator(override val otherSide: Party, + val notary: Party, + override val payload: T, + override val myKeyPair: KeyPair, + override val otherSessionID: Long, + override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { + + override val notaryNode: NodeInfo get() = + serviceHub.networkMapCache.notaryNodes.filter { it.identity == notary }.single() + } /** * One side of the protocol for inserting a pre-agreed deal. */ - open class Acceptor(otherSide: SingleMessageRecipient, - notary: Party, + open class Acceptor(override val otherSide: Party, + val notary: Party, val dealToBuy: T, - sessionID: Long, - override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary(otherSide, notary, sessionID) { + override val sessionID: Long, + override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary() { + override fun validateHandshake(handshake: Handshake): Handshake { - with(handshake) { - // What is the seller trying to sell us? - val deal: T = handshake.payload - val otherKey = handshake.publicKey - logger.trace { "Got deal request for: ${handshake.payload}" } + // What is the seller trying to sell us? + val deal: T = handshake.payload + val otherKey = handshake.publicKey + logger.trace { "Got deal request for: ${handshake.payload.ref}" } - // Check the start message for acceptability. - check(handshake.sessionID > 0) - if (dealToBuy != deal) - throw DealMismatchException(dealToBuy, deal) + // Check the start message for acceptability. + check(handshake.sessionID > 0) + check(dealToBuy == deal) - // We need to substitute in the new public keys for the Parties - val myName = serviceHub.storageService.myLegalIdentity.name - val myOldParty = deal.parties.single { it.name == myName } - val theirOldParty = deal.parties.single { it.name != myName } + // We need to substitute in the new public keys for the Parties + val myName = serviceHub.storageService.myLegalIdentity.name + val myOldParty = deal.parties.single { it.name == myName } + val theirOldParty = deal.parties.single { it.name != myName } - @Suppress("UNCHECKED_CAST") - val newDeal = deal. - withPublicKey(myOldParty, serviceHub.keyManagementService.freshKey().public). - withPublicKey(theirOldParty, otherKey) as T + @Suppress("UNCHECKED_CAST") + val newDeal = deal. + withPublicKey(myOldParty, serviceHub.keyManagementService.freshKey().public). + withPublicKey(theirOldParty, otherKey) as T - return handshake.copy(payload = newDeal) - } + return handshake.copy(payload = newDeal) } @@ -328,59 +341,60 @@ object TwoPartyDealProtocol { * One side of the fixing protocol for an interest rate swap, but could easily be generalised further. * * Do not infer too much from the name of the class. This is just to indicate that it is the "side" - * of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for decided + * of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for deciding * who does what in the protocol. */ - open class Fixer(otherSide: SingleMessageRecipient, - notary: Party, - val dealToFix: StateAndRef, - sessionID: Long, - val replacementProgressTracker: ProgressTracker? = null) : Secondary(otherSide, notary, sessionID) { - private val ratesFixTracker = RatesFixProtocol.tracker(dealToFix.state.data.nextFixingOf()!!.name) + class Fixer(val initiation: FixingSessionInitiation, override val progressTracker: ProgressTracker = Secondary.tracker()) : Secondary() { - override val progressTracker: ProgressTracker = replacementProgressTracker ?: createTracker() + override val sessionID: Long get() = initiation.sessionID - fun createTracker(): ProgressTracker = Secondary.tracker().apply { - setChildProgressTracker(SIGNING, ratesFixTracker) - } + override val otherSide: Party get() = initiation.sender + + private lateinit var txState: TransactionState<*> + private lateinit var deal: FixableDealState override fun validateHandshake(handshake: Handshake): Handshake { - with(handshake) { - logger.trace { "Got fixing request for: ${dealToFix.state}" } + logger.trace { "Got fixing request for: ${handshake.payload}" } - // Check the start message for acceptability. - if (dealToFix.ref != handshake.payload) - throw DealRefMismatchException(dealToFix.ref, handshake.payload) + // Check the handshake and initiation for acceptability. + check(handshake.sessionID > 0) + txState = serviceHub.loadState(handshake.payload) + deal = txState.data as FixableDealState - return handshake - } + // validate the party that initiated is the one on the deal and that the recipient corresponds with it. + // TODO: this is in no way secure and will be replaced by general session initiation logic in the future + val myName = serviceHub.storageService.myLegalIdentity.name + val otherParty = deal.parties.filter { it.name != myName }.single() + check(otherParty == initiation.party) + // Also check we are one of the parties + deal.parties.filter { it.name == myName }.single() + + return handshake } @Suspendable override fun assembleSharedTX(handshake: Handshake): Pair> { - val fixOf = dealToFix.state.data.nextFixingOf()!! + @Suppress("UNCHECKED_CAST") + val fixOf = deal.nextFixingOf()!! // TODO Do we need/want to substitute in new public keys for the Parties? val myName = serviceHub.storageService.myLegalIdentity.name - val deal: T = dealToFix.state.data val myOldParty = deal.parties.single { it.name == myName } - @Suppress("UNCHECKED_CAST") val newDeal = deal val ptx = TransactionType.General.Builder() - val addFixing = object : RatesFixProtocol(ptx, serviceHub.networkMapCache.ratesOracleNodes[0], fixOf, BigDecimal.ZERO, BigDecimal.ONE) { + val addFixing = object : RatesFixProtocol(ptx, serviceHub.networkMapCache.ratesOracleNodes[0].identity, fixOf, BigDecimal.ZERO, BigDecimal.ONE, initiation.timeout) { @Suspendable override fun beforeSigning(fix: Fix) { - newDeal.generateFix(ptx, dealToFix, fix) + newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload), fix) // And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt // to have one. - ptx.setTime(serviceHub.clock.instant(), notary, 30.seconds) + ptx.setTime(serviceHub.clock.instant(), txState.notary, 30.seconds) } } subProtocol(addFixing) - return Pair(ptx, arrayListOf(myOldParty.owningKey)) } } @@ -392,11 +406,75 @@ object TwoPartyDealProtocol { * is just the "side" of the protocol run by the party with the floating leg as a way of deciding who * does what in the protocol. */ - open class Floater(otherSide: SingleMessageRecipient, - otherSessionID: Long, - notary: NodeInfo, - dealToFix: StateAndRef, - myKeyPair: KeyPair, - val sessionID: Long, - override val progressTracker: ProgressTracker = Primary.tracker()) : Primary(dealToFix.ref, otherSide, otherSessionID, myKeyPair, notary) + class Floater(override val payload: StateRef, + override val otherSessionID: Long, + override val progressTracker: ProgressTracker = Primary.tracker()) : Primary() { + @Suppress("UNCHECKED_CAST") + internal val dealToFix: StateAndRef by TransientProperty { + val state = serviceHub.loadState(payload) as TransactionState + StateAndRef(state, payload) + } + + override val myKeyPair: KeyPair get() { + val myName = serviceHub.storageService.myLegalIdentity.name + val publicKey = dealToFix.state.data.parties.filter { it.name == myName }.single().owningKey + return serviceHub.keyManagementService.toKeyPair(publicKey) + } + + override val otherSide: Party get() { + // TODO: what happens if there's no node? Move to messaging taking Party and then handled in messaging layer + val myName = serviceHub.storageService.myLegalIdentity.name + return dealToFix.state.data.parties.filter { it.name != myName }.single() + } + + override val notaryNode: NodeInfo get() = + serviceHub.networkMapCache.notaryNodes.filter { it.identity == dealToFix.state.notary }.single() + } + + + /** Used to set up the session between [Floater] and [Fixer] */ + data class FixingSessionInitiation(val sessionID: Long, val party: Party, val sender: Party, val timeout: Duration) + + /** + * This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing. + * + * It is kicked off as an activity on both participant nodes by the scheduler when it's time for a fixing. If the + * Fixer role is chosen, then that will be initiated by the [FixingSessionInitiation] message sent from the other party and + * handled by the [FixingSessionInitiationHandler]. + * + * TODO: Replace [FixingSessionInitiation] and [FixingSessionInitiationHandler] with generic session initiation logic once it exists. + */ + class FixingRoleDecider(val ref: StateRef, + val timeout: Duration, + override val progressTracker: ProgressTracker = tracker(ref.toString())) : ProtocolLogic() { + + companion object { + class LOADING(ref: String) : ProgressTracker.Step("Loading state $ref to decide fixing role") + + fun tracker(ref: String) = ProgressTracker(LOADING(ref)) + } + + override val topic: String get() = FIX_INITIATE_TOPIC + + @Suspendable + override fun call(): Unit { + progressTracker.nextStep() + val dealToFix = serviceHub.loadState(ref) + // TODO: this is not the eventual mechanism for identifying the parties + val sortedParties = (dealToFix.data as FixableDealState).parties.sortedBy { it.name } + if (sortedParties[0].name == serviceHub.storageService.myLegalIdentity.name) { + // Generate sessionID + val sessionID = random63BitValue() + val initation = FixingSessionInitiation(sessionID, sortedParties[0], serviceHub.storageService.myLegalIdentity, timeout) + + // Send initiation to other side to launch one side of the fixing protocol (the Fixer). + send(sortedParties[1], 0, initation) + + // Then start the other side of the fixing protocol. + val protocol = Floater(ref, sessionID) + subProtocol(protocol) + } + } + } + } \ No newline at end of file diff --git a/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt b/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt index ea36c2fe66..0b45e7f15a 100644 --- a/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt +++ b/core/src/main/kotlin/com/r3corda/protocols/ValidatingNotaryProtocol.kt @@ -6,7 +6,6 @@ import com.r3corda.core.contracts.TransactionVerificationException import com.r3corda.core.contracts.WireTransaction import com.r3corda.core.contracts.toLedgerTransaction import com.r3corda.core.crypto.Party -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.services.TimestampChecker import com.r3corda.core.node.services.UniquenessProvider import java.security.SignatureException @@ -17,7 +16,7 @@ import java.security.SignatureException * has its input states "blocked" by a transaction from another party, and needs to establish whether that transaction was * indeed valid */ -class ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, +class ValidatingNotaryProtocol(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, @@ -52,7 +51,6 @@ class ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, @Suspendable private fun validateDependencies(reqIdentity: Party, wtx: WireTransaction) { - val otherSide = serviceHub.networkMapCache.getNodeByPublicKey(reqIdentity.owningKey)!!.address - subProtocol(ResolveTransactionsProtocol(wtx, otherSide)) + subProtocol(ResolveTransactionsProtocol(wtx, reqIdentity)) } } \ No newline at end of file diff --git a/core/src/main/kotlin/protocols/AbstractStateReplacementProtocol.kt b/core/src/main/kotlin/protocols/AbstractStateReplacementProtocol.kt new file mode 100644 index 0000000000..1aafd6fed8 --- /dev/null +++ b/core/src/main/kotlin/protocols/AbstractStateReplacementProtocol.kt @@ -0,0 +1,237 @@ +package protocols + +import co.paralleluniverse.fibers.Suspendable +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.DigitalSignature +import com.r3corda.core.crypto.Party +import com.r3corda.core.crypto.signWithECDSA +import com.r3corda.core.messaging.Ack +import com.r3corda.core.node.NodeInfo +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.random63BitValue +import com.r3corda.core.utilities.ProgressTracker +import com.r3corda.protocols.NotaryProtocol +import com.r3corda.protocols.PartyRequestMessage +import com.r3corda.protocols.ResolveTransactionsProtocol +import java.security.PublicKey + +/** + * Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. + * Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these + * protocols. + * + * The [Instigator] assembles the transaction for state replacement and sends out change proposals to all participants + * ([Acceptor]) of that state. If participants agree to the proposed change, they each sign the transaction. + * Finally, [Instigator] sends the transaction containing all signatures back to each participant so they can record it and + * use the new updated state for future transactions. + */ +abstract class AbstractStateReplacementProtocol { + interface Proposal { + val stateRef: StateRef + val modification: T + val stx: SignedTransaction + } + + data class Handshake(val sessionIdForSend: Long, + override val replyToParty: Party, + override val sessionID: Long) : PartyRequestMessage + + abstract class Instigator(val originalState: StateAndRef, + val modification: T, + override val progressTracker: ProgressTracker = tracker()) : ProtocolLogic>() { + companion object { + + object SIGNING : ProgressTracker.Step("Requesting signatures from other parties") + + object NOTARY : ProgressTracker.Step("Requesting notary signature") + + fun tracker() = ProgressTracker(SIGNING, NOTARY) + } + + @Suspendable + override fun call(): StateAndRef { + val (stx, participants) = assembleTx() + + progressTracker.currentStep = SIGNING + + val myKey = serviceHub.storageService.myLegalIdentity.owningKey + val me = listOf(myKey) + + val signatures = if (participants == me) { + listOf(getNotarySignature(stx)) + } else { + collectSignatures(participants - me, stx) + } + + val finalTx = stx + signatures + serviceHub.recordTransactions(listOf(finalTx)) + return finalTx.tx.outRef(0) + } + + abstract internal fun assembleProposal(stateRef: StateRef, modification: T, stx: SignedTransaction): Proposal + abstract internal fun assembleTx(): Pair> + + @Suspendable + private fun collectSignatures(participants: List, stx: SignedTransaction): List { + val sessions = mutableMapOf() + + val participantSignatures = participants.map { + val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?: + throw IllegalStateException("Participant $it to state $originalState not found on the network") + val sessionIdForSend = random63BitValue() + sessions[participantNode] = sessionIdForSend + + getParticipantSignature(participantNode, stx, sessionIdForSend) + } + + val allSignatures = participantSignatures + getNotarySignature(stx) + sessions.forEach { send(it.key.identity, it.value, allSignatures) } + + return allSignatures + } + + @Suspendable + private fun getParticipantSignature(node: NodeInfo, stx: SignedTransaction, sessionIdForSend: Long): DigitalSignature.WithKey { + val sessionIdForReceive = random63BitValue() + val proposal = assembleProposal(originalState.ref, modification, stx) + + val handshake = Handshake(sessionIdForSend, serviceHub.storageService.myLegalIdentity, sessionIdForReceive) + sendAndReceive(node.identity, 0, sessionIdForReceive, handshake) + + val response = sendAndReceive(node.identity, sessionIdForSend, sessionIdForReceive, proposal) + val participantSignature = response.validate { + if (it.sig == null) throw StateReplacementException(it.error!!) + else { + check(it.sig.by == node.identity.owningKey) { "Not signed by the required participant" } + it.sig.verifyWithECDSA(stx.txBits) + it.sig + } + } + + return participantSignature + } + + @Suspendable + private fun getNotarySignature(stx: SignedTransaction): DigitalSignature.LegallyIdentifiable { + progressTracker.currentStep = NOTARY + return subProtocol(NotaryProtocol.Client(stx)) + } + } + + abstract class Acceptor(val otherSide: Party, + val sessionIdForSend: Long, + val sessionIdForReceive: Long, + override val progressTracker: ProgressTracker = tracker()) : ProtocolLogic() { + + companion object { + object VERIFYING : ProgressTracker.Step("Verifying state replacement proposal") + + object APPROVING : ProgressTracker.Step("State replacement approved") + + object REJECTING : ProgressTracker.Step("State replacement rejected") + + fun tracker() = ProgressTracker(VERIFYING, APPROVING, REJECTING) + } + + @Suspendable + override fun call() { + progressTracker.currentStep = VERIFYING + val proposal = receive>(sessionIdForReceive).validate { it } + + try { + verifyProposal(proposal) + verifyTx(proposal.stx) + } catch(e: Exception) { + // TODO: catch only specific exceptions. However, there are numerous validation exceptions + // that might occur (tx validation/resolution, invalid proposal). Need to rethink how + // we manage exceptions and maybe introduce some platform exception hierarchy + val myIdentity = serviceHub.storageService.myLegalIdentity + val state = proposal.stateRef + val reason = StateReplacementRefused(myIdentity, state, e.message) + + reject(reason) + return + } + + approve(proposal.stx) + } + + @Suspendable + private fun approve(stx: SignedTransaction) { + progressTracker.currentStep = APPROVING + + val mySignature = sign(stx) + val response = Result.noError(mySignature) + val swapSignatures = sendAndReceive>(otherSide, sessionIdForSend, sessionIdForReceive, response) + + val allSignatures = swapSignatures.validate { signatures -> + signatures.forEach { it.verifyWithECDSA(stx.txBits) } + signatures + } + + val finalTx = stx + allSignatures + finalTx.verify() + serviceHub.recordTransactions(listOf(finalTx)) + } + + @Suspendable + private fun reject(e: StateReplacementRefused) { + progressTracker.currentStep = REJECTING + val response = Result.withError(e) + send(otherSide, sessionIdForSend, response) + } + + /** + * Check the state change proposal to confirm that it's acceptable to this node. Rules for verification depend + * on the change proposed, and may further depend on the node itself (for example configuration). + */ + abstract internal fun verifyProposal(proposal: Proposal) + + @Suspendable + private fun verifyTx(stx: SignedTransaction) { + checkMySignatureRequired(stx.tx) + checkDependenciesValid(stx) + checkValid(stx) + } + + private fun checkMySignatureRequired(tx: WireTransaction) { + // TODO: use keys from the keyManagementService instead + val myKey = serviceHub.storageService.myLegalIdentity.owningKey + require(tx.signers.contains(myKey)) { "Party is not a participant for any of the input states of transaction ${tx.id}" } + } + + @Suspendable + private fun checkDependenciesValid(stx: SignedTransaction) { + val dependencyTxIDs = stx.tx.inputs.map { it.txhash }.toSet() + subProtocol(ResolveTransactionsProtocol(dependencyTxIDs, otherSide)) + } + + private fun checkValid(stx: SignedTransaction) { + val ltx = stx.tx.toLedgerTransaction(serviceHub.identityService, serviceHub.storageService.attachments) + serviceHub.verifyTransaction(ltx) + } + + private fun sign(stx: SignedTransaction): DigitalSignature.WithKey { + val myKeyPair = serviceHub.storageService.myLegalIdentityKey + return myKeyPair.signWithECDSA(stx.txBits) + } + } + + // TODO: similar classes occur in other places (NotaryProtocol), need to consolidate + data class Result private constructor(val sig: DigitalSignature.WithKey?, val error: StateReplacementRefused?) { + companion object { + fun withError(error: StateReplacementRefused) = Result(null, error) + fun noError(sig: DigitalSignature.WithKey) = Result(sig, null) + } + } +} + + +/** Thrown when a participant refuses proposed the state replacement */ +class StateReplacementRefused(val identity: Party, val state: StateRef, val detail: String?) { + override fun toString(): String + = "A participant $identity refused to change state $state" +} + +class StateReplacementException(val error: StateReplacementRefused) +: Exception("State change failed - $error") \ No newline at end of file diff --git a/core/src/main/kotlin/protocols/NotaryChangeProtocol.kt b/core/src/main/kotlin/protocols/NotaryChangeProtocol.kt index b820b45abd..8d587c71fb 100644 --- a/core/src/main/kotlin/protocols/NotaryChangeProtocol.kt +++ b/core/src/main/kotlin/protocols/NotaryChangeProtocol.kt @@ -2,18 +2,8 @@ package protocols import co.paralleluniverse.fibers.Suspendable import com.r3corda.core.contracts.* -import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.Party -import com.r3corda.core.crypto.signWithECDSA -import com.r3corda.core.messaging.Ack -import com.r3corda.core.messaging.SingleMessageRecipient -import com.r3corda.core.node.NodeInfo -import com.r3corda.core.protocols.ProtocolLogic -import com.r3corda.core.random63BitValue import com.r3corda.core.utilities.ProgressTracker -import com.r3corda.protocols.AbstractRequestMessage -import com.r3corda.protocols.NotaryProtocol -import com.r3corda.protocols.ResolveTransactionsProtocol import java.security.PublicKey /** @@ -25,53 +15,27 @@ import java.security.PublicKey * Finally, [Instigator] sends the transaction containing all signatures back to each participant so they can record it and * use the new updated state for future transactions. */ -object NotaryChangeProtocol { - val TOPIC_INITIATE = "platform.notary.change.initiate" - val TOPIC_CHANGE = "platform.notary.change.execute" +object NotaryChangeProtocol: AbstractStateReplacementProtocol() { - data class Proposal(val stateRef: StateRef, - val newNotary: Party, - val stx: SignedTransaction) + val TOPIC = "platform.notary.change" - class Handshake(val sessionIdForSend: Long, - replyTo: SingleMessageRecipient, - replySessionId: Long) : AbstractRequestMessage(replyTo, replySessionId) + data class Proposal(override val stateRef: StateRef, + override val modification: Party, + override val stx: SignedTransaction) : AbstractStateReplacementProtocol.Proposal - class Instigator(val originalState: StateAndRef, - val newNotary: Party, - override val progressTracker: ProgressTracker = tracker()) : ProtocolLogic>() { - companion object { + class Instigator(originalState: StateAndRef, + newNotary: Party, + progressTracker: ProgressTracker = tracker()) + : AbstractStateReplacementProtocol.Instigator(originalState, newNotary, progressTracker) { - object SIGNING : ProgressTracker.Step("Requesting signatures from other parties") + override val topic: String get() = TOPIC - object NOTARY : ProgressTracker.Step("Requesting current Notary signature") + override fun assembleProposal(stateRef: StateRef, modification: Party, stx: SignedTransaction): AbstractStateReplacementProtocol.Proposal + = NotaryChangeProtocol.Proposal(stateRef, modification, stx) - fun tracker() = ProgressTracker(SIGNING, NOTARY) - } - - @Suspendable - override fun call(): StateAndRef { - val (stx, participants) = assembleTx() - - progressTracker.currentStep = SIGNING - - val myKey = serviceHub.storageService.myLegalIdentity.owningKey - val me = listOf(myKey) - - val signatures = if (participants == me) { - listOf(getNotarySignature(stx)) - } else { - collectSignatures(participants - me, stx) - } - - val finalTx = stx + signatures - serviceHub.recordTransactions(listOf(finalTx)) - return finalTx.tx.outRef(0) - } - - private fun assembleTx(): Pair> { + override fun assembleTx(): Pair> { val state = originalState.state - val newState = state.withNewNotary(newNotary) + val newState = state.withNewNotary(modification) val participants = state.data.participants val tx = TransactionType.NotaryChange.Builder().withItems(originalState, newState) tx.signWith(serviceHub.storageService.myLegalIdentityKey) @@ -79,116 +43,15 @@ object NotaryChangeProtocol { val stx = tx.toSignedTransaction(false) return Pair(stx, participants) } - - @Suspendable - private fun collectSignatures(participants: List, stx: SignedTransaction): List { - val sessions = mutableMapOf() - - val participantSignatures = participants.map { - val participantNode = serviceHub.networkMapCache.getNodeByPublicKey(it) ?: - throw IllegalStateException("Participant $it to state $originalState not found on the network") - val sessionIdForSend = random63BitValue() - sessions[participantNode] = sessionIdForSend - - getParticipantSignature(participantNode, stx, sessionIdForSend) - } - - val allSignatures = participantSignatures + getNotarySignature(stx) - sessions.forEach { send(TOPIC_CHANGE, it.key.address, it.value, allSignatures) } - - return allSignatures - } - - @Suspendable - private fun getParticipantSignature(node: NodeInfo, stx: SignedTransaction, sessionIdForSend: Long): DigitalSignature.WithKey { - val sessionIdForReceive = random63BitValue() - val proposal = Proposal(originalState.ref, newNotary, stx) - - val handshake = Handshake(sessionIdForSend, serviceHub.networkService.myAddress, sessionIdForReceive) - sendAndReceive(TOPIC_INITIATE, node.address, 0, sessionIdForReceive, handshake) - - val response = sendAndReceive(TOPIC_CHANGE, node.address, sessionIdForSend, sessionIdForReceive, proposal) - val participantSignature = response.validate { - if (it.sig == null) throw NotaryChangeException(it.error!!) - else { - check(it.sig.by == node.identity.owningKey) { "Not signed by the required participant" } - it.sig.verifyWithECDSA(stx.txBits) - it.sig - } - } - - return participantSignature - } - - @Suspendable - private fun getNotarySignature(stx: SignedTransaction): DigitalSignature.LegallyIdentifiable { - progressTracker.currentStep = NOTARY - return subProtocol(NotaryProtocol.Client(stx)) - } } - class Acceptor(val otherSide: SingleMessageRecipient, - val sessionIdForSend: Long, - val sessionIdForReceive: Long, - override val progressTracker: ProgressTracker = tracker()) : ProtocolLogic() { + class Acceptor(otherSide: Party, + sessionIdForSend: Long, + sessionIdForReceive: Long, + override val progressTracker: ProgressTracker = tracker()) + : AbstractStateReplacementProtocol.Acceptor(otherSide, sessionIdForSend, sessionIdForReceive) { - companion object { - object VERIFYING : ProgressTracker.Step("Verifying Notary change proposal") - - object APPROVING : ProgressTracker.Step("Notary change approved") - - object REJECTING : ProgressTracker.Step("Notary change rejected") - - fun tracker() = ProgressTracker(VERIFYING, APPROVING, REJECTING) - } - - @Suspendable - override fun call() { - progressTracker.currentStep = VERIFYING - val proposal = receive(TOPIC_CHANGE, sessionIdForReceive).validate { it } - - try { - verifyProposal(proposal) - verifyTx(proposal.stx) - } catch(e: Exception) { - // TODO: catch only specific exceptions. However, there are numerous validation exceptions - // that might occur (tx validation/resolution, invalid proposal). Need to rethink how - // we manage exceptions and maybe introduce some platform exception hierarchy - val myIdentity = serviceHub.storageService.myLegalIdentity - val state = proposal.stateRef - val reason = NotaryChangeRefused(myIdentity, state, e.message) - - reject(reason) - return - } - - approve(proposal.stx) - } - - @Suspendable - private fun approve(stx: SignedTransaction) { - progressTracker.currentStep = APPROVING - - val mySignature = sign(stx) - val response = Result.noError(mySignature) - val swapSignatures = sendAndReceive>(TOPIC_CHANGE, otherSide, sessionIdForSend, sessionIdForReceive, response) - - val allSignatures = swapSignatures.validate { signatures -> - signatures.forEach { it.verifyWithECDSA(stx.txBits) } - signatures - } - - val finalTx = stx + allSignatures - finalTx.verify() - serviceHub.recordTransactions(listOf(finalTx)) - } - - @Suspendable - private fun reject(e: NotaryChangeRefused) { - progressTracker.currentStep = REJECTING - val response = Result.withError(e) - send(TOPIC_CHANGE, otherSide, sessionIdForSend, response) - } + override val topic: String get() = TOPIC /** * Check the notary change proposal. @@ -198,8 +61,8 @@ object NotaryChangeProtocol { * TODO: In more difficult cases this should call for human attention to manually verify and approve the proposal */ @Suspendable - private fun verifyProposal(proposal: NotaryChangeProtocol.Proposal) { - val newNotary = proposal.newNotary + override fun verifyProposal(proposal: AbstractStateReplacementProtocol.Proposal) { + val newNotary = proposal.modification val isNotary = serviceHub.networkMapCache.notaryNodes.any { it.identity == newNotary } require(isNotary) { "The proposed node $newNotary does not run a Notary service " } @@ -211,51 +74,5 @@ object NotaryChangeProtocol { val blacklist = listOf("Evil Notary") require(!blacklist.contains(newNotary.name)) { "The proposed new notary $newNotary is not trusted by the party" } } - - @Suspendable - private fun verifyTx(stx: SignedTransaction) { - checkMySignatureRequired(stx.tx) - checkDependenciesValid(stx) - checkValid(stx) - } - - private fun checkMySignatureRequired(tx: WireTransaction) { - // TODO: use keys from the keyManagementService instead - val myKey = serviceHub.storageService.myLegalIdentity.owningKey - require(tx.signers.contains(myKey)) { "Party is not a participant for any of the input states of transaction ${tx.id}" } - } - - @Suspendable - private fun checkDependenciesValid(stx: SignedTransaction) { - val dependencyTxIDs = stx.tx.inputs.map { it.txhash }.toSet() - subProtocol(ResolveTransactionsProtocol(dependencyTxIDs, otherSide)) - } - - private fun checkValid(stx: SignedTransaction) { - val ltx = stx.tx.toLedgerTransaction(serviceHub.identityService, serviceHub.storageService.attachments) - serviceHub.verifyTransaction(ltx) - } - - private fun sign(stx: SignedTransaction): DigitalSignature.WithKey { - val myKeyPair = serviceHub.storageService.myLegalIdentityKey - return myKeyPair.signWithECDSA(stx.txBits) - } } - - // TODO: similar classes occur in other places (NotaryProtocol), need to consolidate - data class Result private constructor(val sig: DigitalSignature.WithKey?, val error: NotaryChangeRefused?) { - companion object { - fun withError(error: NotaryChangeRefused) = Result(null, error) - fun noError(sig: DigitalSignature.WithKey) = Result(sig, null) - } - } -} - -/** Thrown when a participant refuses to change the notary of the state */ -class NotaryChangeRefused(val identity: Party, val state: StateRef, val cause: String?) { - override fun toString() = "A participant $identity refused to change the notary of state $state" -} - -class NotaryChangeException(val error: NotaryChangeRefused) : Exception() { - override fun toString() = "${super.toString()}: Notary change failed - ${error.toString()}" } \ No newline at end of file diff --git a/core/src/test/java/com/r3corda/core/protocols/ProtocolLogicRefFromJavaTest.java b/core/src/test/java/com/r3corda/core/protocols/ProtocolLogicRefFromJavaTest.java new file mode 100644 index 0000000000..b17b1fde80 --- /dev/null +++ b/core/src/test/java/com/r3corda/core/protocols/ProtocolLogicRefFromJavaTest.java @@ -0,0 +1,83 @@ +package com.r3corda.core.protocols; + + +import org.jetbrains.annotations.NotNull; +import org.junit.Test; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +public class ProtocolLogicRefFromJavaTest { + + public static class ParamType1 { + public final int value; + + ParamType1(int v) { + value = v; + } + } + + public static class ParamType2 { + public final String value; + + ParamType2(String v) { + value = v; + } + } + + public static class JavaProtocolLogic extends ProtocolLogic { + + public JavaProtocolLogic(ParamType1 A, ParamType2 b) { + } + + @Override + public Void call() { + return null; + } + + @NotNull + @Override + protected String getTopic() { + throw new UnsupportedOperationException(); + } + } + + public static class JavaNoArgProtocolLogic extends ProtocolLogic { + + public JavaNoArgProtocolLogic() { + } + + @Override + public Void call() { + return null; + } + + @NotNull + @Override + protected String getTopic() { + throw new UnsupportedOperationException(); + } + } + + @Test + public void test() { + Map> whiteList = new HashMap<>(); + Set argsList = new HashSet<>(); + argsList.add(ParamType1.class.getName()); + argsList.add(ParamType2.class.getName()); + whiteList.put(JavaProtocolLogic.class.getName(), argsList); + ProtocolLogicRefFactory factory = new ProtocolLogicRefFactory(whiteList); + factory.create(JavaProtocolLogic.class, new ParamType1(1), new ParamType2("Hello Jack")); + } + + @Test + public void testNoArg() { + Map> whiteList = new HashMap<>(); + Set argsList = new HashSet<>(); + whiteList.put(JavaNoArgProtocolLogic.class.getName(), argsList); + ProtocolLogicRefFactory factory = new ProtocolLogicRefFactory(whiteList); + factory.create(JavaNoArgProtocolLogic.class); + } +} diff --git a/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGraphSearchTests.kt b/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGraphSearchTests.kt index 195fde036f..a6630302f3 100644 --- a/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGraphSearchTests.kt +++ b/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGraphSearchTests.kt @@ -28,12 +28,12 @@ class TransactionGraphSearchTests { */ fun buildTransactions(command: CommandData, signer: KeyPair): GraphTransactionStorage { val originTx = TransactionType.General.Builder().apply { - addOutputState(DummyContract.State(random31BitValue()), DUMMY_NOTARY) + addOutputState(DummyState(random31BitValue()), DUMMY_NOTARY) addCommand(command, signer.public) signWith(signer) }.toSignedTransaction(false) val inputTx = TransactionType.General.Builder().apply { - addInputState(originTx.tx.outRef(0)) + addInputState(originTx.tx.outRef(0)) signWith(signer) }.toSignedTransaction(false) return GraphTransactionStorage(originTx, inputTx) diff --git a/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGroupTests.kt b/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGroupTests.kt index c9143a06a6..6fb59ef18c 100644 --- a/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGroupTests.kt +++ b/core/src/test/kotlin/com/r3corda/core/contracts/TransactionGroupTests.kt @@ -47,33 +47,36 @@ class TransactionGroupTests { @Test fun success() { - transactionGroup { - roots { - transaction(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY label "£1000") + ledger { + unverifiedTransaction { + output("£1000") { A_THOUSAND_POUNDS } } transaction { input("£1000") output("alice's £1000") { A_THOUSAND_POUNDS `owned by` ALICE_PUBKEY } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + this.verifies() } transaction { input("alice's £1000") - arg(ALICE_PUBKEY) { TestCash.Commands.Move() } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) } + command(ALICE_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) } + this.verifies() } - verify() + this.verifies() } } @Test fun conflict() { - transactionGroup { + ledger { val t = transaction { output("cash") { A_THOUSAND_POUNDS } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + this.verifies() } val conflict1 = transaction { @@ -81,10 +84,11 @@ class TransactionGroupTests { val HALF = A_THOUSAND_POUNDS.copy(amount = 500.POUNDS) `owned by` BOB_PUBKEY output { HALF } output { HALF } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + this.verifies() } - verify() + verifies() // Alice tries to double spend back to herself. val conflict2 = transaction { @@ -92,13 +96,14 @@ class TransactionGroupTests { val HALF = A_THOUSAND_POUNDS.copy(amount = 500.POUNDS) `owned by` ALICE_PUBKEY output { HALF } output { HALF } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + this.verifies() } assertNotEquals(conflict1, conflict2) val e = assertFailsWith(TransactionConflictException::class) { - verify() + verifies() } assertEquals(StateRef(t.id, 0), e.conflictRef) assertEquals(setOf(conflict1.id, conflict2.id), setOf(e.tx1.id, e.tx2.id)) @@ -108,79 +113,83 @@ class TransactionGroupTests { @Test fun disconnected() { // Check that if we have a transaction in the group that doesn't connect to anything else, it's rejected. - val tg = transactionGroup { + val tg = ledger { transaction { output("cash") { A_THOUSAND_POUNDS } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + this.verifies() } transaction { input("cash") output { A_THOUSAND_POUNDS `owned by` BOB_PUBKEY } + this.verifies() } } - // We have to do this manually without the DSL because transactionGroup { } won't let us create a tx that - // points nowhere. val input = StateAndRef(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY, generateStateRef()) - tg.txns += TransactionType.General.Builder().apply { - addInputState(input) - addOutputState(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY) - addCommand(TestCash.Commands.Move(), BOB_PUBKEY) - }.toWireTransaction() - - val e = assertFailsWith(TransactionResolutionException::class) { - tg.verify() + tg.apply { + transaction { + assertFailsWith(TransactionResolutionException::class) { + input(input.ref) + } + this.verifies() + } } - assertEquals(e.hash, input.ref.txhash) } @Test fun duplicatedInputs() { // Check that a transaction cannot refer to the same input more than once. - transactionGroup { - roots { - transaction(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY label "£1000") + ledger { + unverifiedTransaction { + output("£1000") { A_THOUSAND_POUNDS } } transaction { input("£1000") input("£1000") output { A_THOUSAND_POUNDS.copy(amount = A_THOUSAND_POUNDS.amount * 2) } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + this.verifies() } assertFailsWith(TransactionConflictException::class) { - verify() + verifies() } } } @Test fun signGroup() { - val signedTxns: List = transactionGroup { + ledger { transaction { output("£1000") { A_THOUSAND_POUNDS } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() } + this.verifies() } transaction { input("£1000") output("alice's £1000") { A_THOUSAND_POUNDS `owned by` ALICE_PUBKEY } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Move() } + this.verifies() } transaction { input("alice's £1000") - arg(ALICE_PUBKEY) { TestCash.Commands.Move() } - arg(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) } + command(ALICE_PUBKEY) { TestCash.Commands.Move() } + command(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) } + this.verifies() } - }.signAll() - // Now go through the conversion -> verification path with them. - val ltxns = signedTxns.map { - it.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) - }.toSet() - TransactionGroup(ltxns, emptySet()).verify() + val signedTxns: List = signAll() + + // Now go through the conversion -> verification path with them. + val ltxns = signedTxns.map { + it.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) + }.toSet() + TransactionGroup(ltxns, emptySet()).verify() + } } } diff --git a/core/src/test/kotlin/com/r3corda/core/contracts/clauses/VerifyClausesTests.kt b/core/src/test/kotlin/com/r3corda/core/contracts/clauses/VerifyClausesTests.kt new file mode 100644 index 0000000000..b97d943745 --- /dev/null +++ b/core/src/test/kotlin/com/r3corda/core/contracts/clauses/VerifyClausesTests.kt @@ -0,0 +1,114 @@ +package com.r3corda.core.contracts.clauses + +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.SecureHash +import org.junit.Test +import kotlin.test.assertFailsWith + +/** + * Tests for the clause verifier. + */ +class VerifyClausesTests { + /** Check that if there's no clauses, verification passes. */ + @Test + fun `passes empty clauses`() { + val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) + verifyClauses(tx, emptyList(), emptyList>()) + } + + /** Very simple check that the function doesn't error when given any clause */ + @Test + fun minimal() { + val clause = object : SingleClause { + override val requiredCommands: Set> + get() = emptySet() + override val ifMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + override val ifNotMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + + override fun verify(tx: TransactionForContract, commands: Collection>): Set = emptySet() + } + val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) + verifyClauses(tx, listOf(clause), emptyList>()) + } + + /** Check that when there are no required commands, a clause always matches */ + @Test + fun emptyAlwaysMatches() { + val clause = object : SingleClause { + override val requiredCommands: Set> + get() = emptySet() + override val ifMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + override val ifNotMatched: MatchBehaviour + get() = MatchBehaviour.ERROR + + override fun verify(tx: TransactionForContract, commands: Collection>): Set = emptySet() + } + val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) + // This would error if it wasn't matched + verifyClauses(tx, listOf(clause), emptyList>()) + } + + @Test + fun errorSuperfluousCommands() { + val clause = object : SingleClause { + override val requiredCommands: Set> + get() = emptySet() + override val ifMatched: MatchBehaviour + get() = MatchBehaviour.ERROR + override val ifNotMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + + override fun verify(tx: TransactionForContract, commands: Collection>): Set + = emptySet() + } + val command = AuthenticatedObject(emptyList(), emptyList(), DummyContract.Commands.Create()) + val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), listOf(command), SecureHash.randomSHA256()) + // The clause is matched, but doesn't mark the command as consumed, so this should error + assertFailsWith { verifyClauses(tx, listOf(clause), listOf(command)) } + } + + /** Check triggering of error if matched */ + @Test + fun errorMatched() { + val clause = object : SingleClause { + override val requiredCommands: Set> + get() = setOf(DummyContract.Commands.Create::class.java) + override val ifMatched: MatchBehaviour + get() = MatchBehaviour.ERROR + override val ifNotMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + + override fun verify(tx: TransactionForContract, commands: Collection>): Set + = commands.select().map { it.value }.toSet() + } + var tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) + + // This should pass as it doesn't match + verifyClauses(tx, listOf(clause), emptyList()) + + // This matches and should throw an error + val command = AuthenticatedObject(emptyList(), emptyList(), DummyContract.Commands.Create()) + tx = TransactionForContract(emptyList(), emptyList(), emptyList(), listOf(command), SecureHash.randomSHA256()) + assertFailsWith { verifyClauses(tx, listOf(clause), listOf(command)) } + } + + /** Check triggering of error if unmatched */ + @Test + fun errorUnmatched() { + val clause = object : SingleClause { + override val requiredCommands: Set> + get() = setOf(DummyContract.Commands.Create::class.java) + override val ifMatched: MatchBehaviour + get() = MatchBehaviour.CONTINUE + override val ifNotMatched: MatchBehaviour + get() = MatchBehaviour.ERROR + + override fun verify(tx: TransactionForContract, commands: Collection>): Set = emptySet() + } + val tx = TransactionForContract(emptyList(), emptyList(), emptyList(), emptyList(), SecureHash.randomSHA256()) + assertFailsWith { verifyClauses(tx, listOf(clause), emptyList()) } + } +} \ No newline at end of file diff --git a/core/src/test/kotlin/com/r3corda/core/protocols/ProtocolLogicRefTest.kt b/core/src/test/kotlin/com/r3corda/core/protocols/ProtocolLogicRefTest.kt new file mode 100644 index 0000000000..aa5651f12d --- /dev/null +++ b/core/src/test/kotlin/com/r3corda/core/protocols/ProtocolLogicRefTest.kt @@ -0,0 +1,103 @@ +package com.r3corda.core.protocols + +import com.r3corda.core.days +import org.junit.Before +import org.junit.Test +import java.time.Duration + +class ProtocolLogicRefTest { + + data class ParamType1(val value: Int) + data class ParamType2(val value: String) + + @Suppress("UNUSED_PARAMETER") // We will never use A or b + class KotlinProtocolLogic(A: ParamType1, b: ParamType2) : ProtocolLogic() { + constructor() : this(ParamType1(1), ParamType2("2")) + + constructor(C: ParamType2) : this(ParamType1(1), C) + + constructor(illegal: Duration) : this(ParamType1(1), ParamType2(illegal.toString())) + + constructor(primitive: String) : this(ParamType1(1), ParamType2(primitive)) + + constructor(kotlinType: Int) : this(ParamType1(kotlinType), ParamType2("b")) + + override fun call(): Unit { + } + + override val topic: String get() = throw UnsupportedOperationException() + } + + class KotlinNoArgProtocolLogic : ProtocolLogic() { + override fun call(): Unit { + } + override val topic: String get() = throw UnsupportedOperationException() + } + + @Suppress("UNUSED_PARAMETER") // We will never use A or b + class NotWhiteListedKotlinProtocolLogic(A: Int, b: String) : ProtocolLogic() { + override fun call(): Unit { + } + override val topic: String get() = throw UnsupportedOperationException() + } + + lateinit var factory: ProtocolLogicRefFactory + + @Before + fun setup() { + // We have to allow Java boxed primitives but Kotlin warns we shouldn't be using them + factory = ProtocolLogicRefFactory(mapOf(Pair(KotlinProtocolLogic::class.java.name, setOf(ParamType1::class.java.name, ParamType2::class.java.name)), + Pair(KotlinNoArgProtocolLogic::class.java.name, setOf()))) + } + + @Test + fun testCreateKotlinNoArg() { + factory.create(KotlinNoArgProtocolLogic::class.java) + } + + @Test + fun testCreateKotlin() { + val args = mapOf(Pair("A", ParamType1(1)), Pair("b", ParamType2("Hello Jack"))) + factory.createKotlin(KotlinProtocolLogic::class.java, args) + } + + @Test + fun testCreatePrimary() { + factory.create(KotlinProtocolLogic::class.java, ParamType1(1), ParamType2("Hello Jack")) + } + + @Test(expected = IllegalArgumentException::class) + fun testCreateNotWhiteListed() { + factory.create(NotWhiteListedKotlinProtocolLogic::class.java, ParamType1(1), ParamType2("Hello Jack")) + } + + @Test + fun testCreateKotlinVoid() { + factory.createKotlin(KotlinProtocolLogic::class.java, emptyMap()) + } + + @Test + fun testCreateKotlinNonPrimary() { + val args = mapOf(Pair("C", ParamType2("Hello Jack"))) + factory.createKotlin(KotlinProtocolLogic::class.java, args) + } + + @Test(expected = IllegalArgumentException::class) + fun testCreateArgNotWhiteListed() { + val args = mapOf(Pair("illegal", 1.days)) + factory.createKotlin(KotlinProtocolLogic::class.java, args) + } + + @Test + fun testCreateJavaPrimitiveNoRegistrationRequired() { + val args = mapOf(Pair("primitive", "A string")) + factory.createKotlin(KotlinProtocolLogic::class.java, args) + } + + @Test + fun testCreateKotlinPrimitiveNoRegistrationRequired() { + val args = mapOf(Pair("kotlinType", 3)) + factory.createKotlin(KotlinProtocolLogic::class.java, args) + } + +} diff --git a/docs/build/html/_sources/codestyle.txt b/docs/build/html/_sources/codestyle.txt index 2e15c7fd28..aeebb4f04d 100644 --- a/docs/build/html/_sources/codestyle.txt +++ b/docs/build/html/_sources/codestyle.txt @@ -185,3 +185,38 @@ instead do this The latter is easier to catch and handle if later necessary, and the type name should explain what went wrong. Note that Kotlin does not require exception types to be declared in method prototypes like Java does. + +5. Properties +############# + +Where we want a public property to have one super-type in public and another sub-type in private (or internal), perhaps +to expose additional methods with a greater level of access to the code within the enclosing class, the style should be: + +.. sourcecode:: kotlin + + class PrivateFoo : PublicFoo + + private val _foo = PrivateFoo() + val foo: PublicFoo get() = _foo + +Notably: + +* The public property should have an explicit and more restrictive type, most likely a super class or interface. +* The private, backed property should begin with underscore but otherwise have the same name as the public property. + The underscore resolves a potential property name clash, and avoids naming such as "privateFoo". If the type or use + of the private property is different enough that there is no naming collision, prefer the distinct names without + an underscore. +* The underscore prefix is not a general pattern for private properties. +* The public property should not have an additional backing field but use "get()" to return an appropriate copy of the + private field. +* The public property should optionally wrap the returned value in an immutable wrapper, such as Guava's immutable + collection wrappers, if that is appropriate. +* If the code following "get()" is succinct, prefer a one-liner formatting of the public property as above, otherwise + put the "get()" on the line below, indented. + +6. Compiler warnings +#################### + +We do not allow compiler warnings, except in the experimental module where the usual standards do not apply and warnings +are suppressed. If a warning exists it should be either fixed or suppressed using @SuppressWarnings and if suppressed +there must be an accompanying explanation in the code for why the warning is a false positive. \ No newline at end of file diff --git a/docs/build/html/_sources/consensus.txt b/docs/build/html/_sources/consensus.txt index ee71767d50..85e789acf9 100644 --- a/docs/build/html/_sources/consensus.txt +++ b/docs/build/html/_sources/consensus.txt @@ -1,11 +1,11 @@ -Consensus Model +Consensus model =============== The fundamental unit of consensus in Corda is the **state**. The concept of consensus can be divided into two parts: 1. Consensus over state **validity** -- parties can reach certainty that a transaction defining output states is accepted by the contracts pointed to by the states and has all the required signatures. This is achieved by parties independently running the same contract code and validation logic (as described in :doc:`data model `) -2. Consensus over state **uniqueness** -- parties can reach certainty the the output states created in a transaction are the unique successors to the input states consumed by that transaction (in other words -- a state has not been used as an input by more than one transaction) +2. Consensus over state **uniqueness** -- parties can reach certainty the output states created in a transaction are the unique successors to the input states consumed by that transaction (in other words -- a state has not been used as an input by more than one transaction) This article presents an initial model for addressing the **uniqueness** problem. @@ -15,104 +15,133 @@ Notary ------ We introduce the concept of a **Notary**, which is an authority responsible for attesting that for a given transaction, it had not signed another transaction consuming any of its input states. -The data model is extended so that every **state** has an appointed Notary: +The data model is extended so that every **state** has an appointed notary: .. sourcecode:: kotlin - interface ContractState { - /** Contract by which the state belongs */ - val contract: Contract - - /** Identity of the notary that ensures this state is not used as an input to a transaction more than once */ - val notary: Party + /** + * A wrapper for [ContractState] containing additional platform-level state information. + * This is the definitive state that is stored on the ledger and used in transaction outputs + */ + data class TransactionState( + /** The custom contract state */ + val data: T, + /** Identity of the notary that ensures the state is not used as an input to a transaction more than once */ + val notary: Party) { + ... } -All transactions have to be signed by their input state Notary for the output states to be **valid** (apart from *issue* transactions, containing no input states). +All transactions have to be signed by their input state notary for the output states to be **valid** (apart from *issue* transactions, containing no input states). -.. note:: The Notary is a logical concept and can itself be a distributed entity, potentially a cluster maintained by mutually distrusting parties +.. note:: The notary is a logical concept and can itself be a distributed entity, potentially a cluster maintained by mutually distrusting parties -When the Notary is requested to sign a transaction, it either signs over it, attesting that the outputs are the **unique** successors of the inputs, +When the notary is requested to sign a transaction, it either signs over it, attesting that the outputs are the **unique** successors of the inputs, or provides conflict information for any input state that had been consumed by another transaction it had signed before. -In doing so, the Notary provides the point of finality in the system. Until the Notary signature is obtained, parties cannot be sure that an equally valid, but conflicting transaction, +In doing so, the notary provides the point of finality in the system. Until the notary signature is obtained, parties cannot be sure that an equally valid, but conflicting transaction, will not be regarded as confirmed. After the signature is obtained, the parties know that the inputs to this transaction have been uniquely consumed by this transaction. Hence it is the point at which we can say finality has occurred. +Multiple notaries +----------------- + +More than one notary can exist in the network. This gives the following benefits: + +* **Custom behaviour**. We can have both validating and privacy preserving Notaries -- parties can make a choice based on their specific requirements +* **Load balancing**. Spreading the transaction load over multiple Notaries will allow higher transaction throughput in the platform overall +* **Low latency**. Latency could be minimised by choosing a notary physically closer the transacting parties + +A transaction should only be signed by a notary if all of its input states point to it. +In cases where a transaction involves states controlled by multiple notaries, the states first have to be repointed to the same notary. +This is achieved by using a special type of transaction that doesn't modify anything but the notary pointer of the state. +Ensuring that all input states point to the same notary is the responsibility of each involved party +(it is another condition for an output state of the transaction to be **valid**) + Validation ---------- -The Notary *does not validate* transaction integrity (i.e. does not run contracts or check signatures) to minimise the exposed data. -Validation would require the caller to reveal the whole transaction history chain, resulting in a privacy leak. +One of the design decisions for a notary is whether or not to **validate** a transaction before committing its input states. -However, this makes it open to "denial of state" attacks, where a party could submit any invalid transaction to the Notary and thus "block" someone else's states. -That is partially alleviated by requiring the calling party to authenticate and storing its identity for the request. +If a transaction is not checked for validity, it opens the platform to "denial of state" attacks, where anyone can build an invalid transaction consuming someone else's states and submit it to the notary to get the states "blocked". +However, validation of a transaction requires the notary to be able to see the full contents of the transaction in question and its dependencies. +This is an obvious privacy leak. + +Our platform is flexible and we currently support both validating and non-validating notary implementations -- a party can select which one to use based on its own privacy requirements. + +.. note:: In the non-validating model the "denial of state" attack is partially alleviated by requiring the calling party to authenticate and storing its identity for the request. The conflict information returned by the Notary specifies the consuming transaction id along with the identity of the party that had requested the commit. -If the conflicting transaction is valid, the current one gets aborted; if not – a dispute can be raised and the input states of the conflicting invalid transaction are "un-committed" (to be covered by legal process). + If the conflicting transaction is valid, the current one gets aborted; if not – a dispute can be raised and the input states of the conflicting invalid transaction are "un-committed" (to be covered by legal process). -.. note:: At present the Notary can see the entire transaction, but we have a separate piece of work to replace the parts of the transaction it does not require knowing about with hashes (only input references, timestamp information, overall transaction ID and the necessary digests of the rest of the transaction to prove that the referenced inputs/timestamps really do form part of the stated transaction ID should be visible). - -Multiple Notaries ------------------ - -More than one Notary can exist in the network. This gives the following benefits: - -* **Custom behaviour**. We can have both validating and privacy preserving Notaries -- parties can make a choice based on their specific requirements -* **Load balancing**. Spreading the transaction load over multiple Notaries will allow higher transaction throughput in the platform overall -* **Low latency**. Latency could be minimised by choosing a Notary physically closer the transacting parties - -A transaction should only be signed by a Notary if all of its input states point to it. -In cases where a transaction involves states controlled by multiple Notaries, the states first have to be repointed to the same notary. -This is achieved by using a special type of transaction that doesn't modify anything but the Notary pointer of the state. -Ensuring that all input states point to the same Notary is the responsibility of each involved party -(it is another condition for an output state of the transaction to be **valid**) +.. note:: At present all notaries can see the entire contents of a transaction, but we have a separate piece of work to replace the parts of the transaction it does not require knowing about with hashes (only input references, timestamp information, overall transaction ID and the necessary digests of the rest of the transaction to prove that the referenced inputs/timestamps really do form part of the stated transaction ID should be visible). Timestamping ------------ -In this model the Notary also acts as a **Timestamping Authority**, verifying the transaction timestamp command. +In this model the notary also acts as a **Timestamping Authority**, verifying the transaction timestamp command. For a timestamp to be meaningful, its implications must be binding on the party requesting it. A party can obtain a timestamp signature in order to prove that some event happened before/on/or after a particular point in time. However, if the party is not also compelled to commit to the associated transaction, it has a choice of whether or not to reveal this fact until some point in the future. -As a result, we need to ensure that the Notary either has to also sign the transaction within some time tolerance, +As a result, we need to ensure that the notary either has to also sign the transaction within some time tolerance, or perform timestamping *and* notarisation at the same time, which is the chosen behaviour for this model. -Implementation & Usage ----------------------- +Running a Notary Service +------------------------ -At present we have single basic implementation of a Notary that uses a :code:`UniquenessProvider` storing committed input states in memory: +At present we have two basic implementations that store committed input states in memory: -.. sourcecode:: kotlin +- ``SimpleNotaryService`` -- commits the provided transaction without any validation - class InMemoryUniquenessProvider() : UniquenessProvider { - /** For each input state store the consuming transaction information */ - private val committedStates = HashMap() +- ``ValidatingNotaryService`` -- retrieves and validates the whole transaction history (including the given transaction) before committing - override fun commit(tx: WireTransaction, callerIdentity: Party) { - ... - } - } - ... - /** - * Specifies the transaction id, the position of the consumed state in the inputs, and - * the caller identity requesting the commit - */ - data class ConsumingTx(val id: SecureHash, val inputIndex: Int, val requestingParty: Party) +To run one of these services the node has to simply specify either ``SimpleNotaryService.Type`` or ``ValidatingNotaryService.Type`` in its ``advertisedServices`` set, and the correct type will be initialised. -To obtain a signature from a Notary use :code:`NotaryProtocol`, passing in a :code:`WireTransaction`. -The protocol will work out which Notary needs to be called based on the input states and the timestamp command. +Obtaining a signature +--------------------- + +To obtain a signature from a notary use ``NotaryProtocol.Client``, passing in a ``WireTransaction``. +The protocol will work out which notary needs to be called based on the input states and the timestamp command. For example, the following snippet can be used when writing a custom protocol: .. sourcecode:: kotlin - private fun getNotarySignature(wtx: WireTransaction): DigitalSignature.LegallyIdentifiable { - return subProtocol(NotaryProtocol(wtx)) + fun getNotarySignature(wtx: WireTransaction): DigitalSignature.LegallyIdentifiable { + return subProtocol(NotaryProtocol.Client(wtx)) } -On conflict the :code:`NotaryProtocol` with throw a :code:`NotaryException` containing the conflict details: +On conflict the ``NotaryProtocol`` with throw a ``NotaryException`` containing the conflict details: .. sourcecode:: kotlin /** Specifies the consuming transaction for the conflicting input state */ data class Conflict(val stateHistory: Map) -Conflict handling and resolution is currently the responsibility of the protocol author. \ No newline at end of file + /** + * Specifies the transaction id, the position of the consumed state in the inputs, and + * the caller identity requesting the commit + */ + data class ConsumingTx(val id: SecureHash, val inputIndex: Int, val requestingParty: Party) + +Conflict handling and resolution is currently the responsibility of the protocol author. + +Changing notaries +----------------- + +To change the notary for an input state, use the ``NotaryChangeProtocol``. For example: + +.. sourcecode:: kotlin + + fun changeNotary(originalState: StateAndRef, + newNotary: Party): StateAndRef { + val protocol = NotaryChangeProtocol.Instigator(originalState, newNotary) + return subProtocol(protocol) + } + +The protocol will: + +1. Construct a transaction with the old state as the input and the new state as the output + +2. Obtain signatures from all *participants* (a participant is any party that is able to consume this state in a valid transaction, as defined by the state itself) + +3. Obtain the *old* notary signature + +4. Record and distribute the final transaction to the participants so that everyone possesses the new state \ No newline at end of file diff --git a/docs/build/html/_sources/event-scheduling.txt b/docs/build/html/_sources/event-scheduling.txt new file mode 100644 index 0000000000..9c2cacfd92 --- /dev/null +++ b/docs/build/html/_sources/event-scheduling.txt @@ -0,0 +1,102 @@ +.. highlight:: kotlin +.. raw:: html + + + + +Event scheduling +================ + +This article explains our experimental approach to modelling time based events in code. It explains how a contract +state can expose an upcoming event and what action to take if the scheduled time for that event is reached. + +Introduction +------------ + +Many financial instruments have time sensitive components to them. For example, an Interest Rate Swap has a schedule +for when: + +* Interest rate fixings should take place for floating legs, so that the interest rate used as the basis for payments + can be agreed. +* Any payments between the parties are expected to take place. +* Any payments between the parties become overdue. + +Each of these is dependent on the current state of the financial instrument. What payments and interest rate fixings +have already happened should already be recorded in the state, for example. This means that the *next* time sensitive +event is thus a property of the current contract state. By next, we mean earliest in chronological terms, that is still +due. If a contract state is consumed in the UTXO model, then what *was* the next event becomes irrelevant and obsolete +and the next time sensitive event is determined by any successor contract state. + +Knowing when the next time sensitive event is due to occur is useful, but typically some *activity* is expected to take +place when this event occurs. We already have a model for business processes in the form of the protocol state machines, +so in the platform we have introduced the concept of *scheduled activities* that can invoke protocol state machines +at a scheduled time. A contract state can optionally described the next scheduled activity for itself. If it omits +to do so, then nothing will be scheduled. + +How to implement scheduled events +--------------------------------- + +There are two main steps to implementing scheduled events: + +* Have your ``ContractState`` implementation also implement ``SchedulableState``. This requires a method named + ``nextScheduledActivity`` to be implemented which returns an optional ``ScheduledActivity`` instance. + ``ScheduledActivity`` captures what ``ProtocolLogic`` instance each node will run, to perform the activity, and when it + will run is described by a ``java.time.Instant``. Once your state implements this interface and is tracked by the + wallet, it can expect to be queried for the next activity when recorded via the ``ServiceHub.recordTransactions`` + method during protocols execution. +* If nothing suitable exists, implement a ``ProtocolLogic`` to be executed by each node as the activity itself. + The important thing to remember is that each node that is party to the transaction, in the current implementation, + will execute the same ``ProtocolLogic`` so that needs to establish roles in the business process based on the contract + state and the node it is running on, and follow different but complementary paths through the business logic. + +.. note:: The scheduler's clock always operates in the UTC time zone for uniformity, so any time zone logic must be + performed by the contract, using ``ZonedDateTime``. + +In the short term, until we have automatic protocol session set up, you will also likely need to install a network +handler to help with obtaining a unqiue and secure random session. An example is described below. + +The production and consumption of ``ContractStates`` is observed by the scheduler and the activities associated with +any consumed states are unscheduled. Any newly produced states are then queried via the ``nextScheduledActivity`` +method and if they do not return ``null`` then that activity is scheduled based on the content of the +``ScheduledActivity`` object returned. + +An example +---------- + +Let's take an example of the Interest Rate Swap fixings for our scheduled events. The first task is to implement the +``nextScheduledActivity`` method on the ``State``. + + +.. container:: codeset + + .. sourcecode:: kotlin + + override fun nextScheduledActivity(thisStateRef: StateRef, + protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity? { + val nextFixingOf = nextFixingOf() ?: return null + + // This is perhaps not how we should determine the time point in the business day, but instead expect the + // schedule to detail some of these aspects. + val (instant, duration) = suggestInterestRateAnnouncementTimeWindow(index = nextFixingOf.name, + source = floatingLeg.indexSource, + date = nextFixingOf.forDay) + return ScheduledActivity(protocolLogicRefFactory.create(TwoPartyDealProtocol.FixingRoleDecider::class.java, + thisStateRef, duration), instant) + } + +The first thing this does is establish if there are any remaining fixings. If there are none, then it returns ``null`` +to indicate that there is no activity to schedule. Otherwise it calculates the ``Instant`` at which the interest rate +should become available and schedules an activity at that time to work out what roles each node will take in the fixing +business process and to take on those roles. That ``ProtocolLogic`` will be handed the ``StateRef`` for the interest +rate swap ``State`` in question, as well as a tolerance ``Duration`` of how long to wait after the activity is triggered +for the interest rate before indicating an error. + +.. note:: The use of the factory to create a ``ProtocolLogicRef`` instance to embed in the ``ScheduledActivity``. This is a + way to create a reference to the ``ProtocolLogic`` class and it's constructor parameters to instantiate that can be + checked against a per node whitelist of approved and allowable types as part of our overall security sandboxing. + +As previously mentioned, we currently need a small network handler to assist with session setup until the work to +automate that is complete. See the interest rate swap specific implementation ``FixingSessionInitiationHandler`` which +is responsible for starting a ``ProtocolLogic`` to perform one role in the fixing protocol with the ``sessionID`` sent +by the ``FixingRoleDecider`` on the other node which then launches the other role in the fixing protocol. Currently +the handler needs to be manually installed in the node. diff --git a/docs/build/html/_sources/index.txt b/docs/build/html/_sources/index.txt index f18a72c5a4..df3e876da5 100644 --- a/docs/build/html/_sources/index.txt +++ b/docs/build/html/_sources/index.txt @@ -41,6 +41,7 @@ Read on to learn: tutorial-contract protocol-state-machines oracles + event-scheduling .. toctree:: :maxdepth: 2 diff --git a/docs/build/html/_sources/inthebox.txt b/docs/build/html/_sources/inthebox.txt index 690932881c..25ed8e2afa 100644 --- a/docs/build/html/_sources/inthebox.txt +++ b/docs/build/html/_sources/inthebox.txt @@ -1,46 +1,46 @@ What's included? ================ -The current prototype consists of a small amount of code that defines: +The Corda prototype currently includes: -* Key data structures. +* A peer to peer network with message persistence and delivery retries. +* Key data structures for defining contracts and states. +* Smart contracts: + * Cash + * Cash obligations + * Interest rate swaps + * Commercial paper (implemented in both Java and Kotlin for comparison) * Algorithms that work with them, such as serialising, hashing, signing, and verification of the signatures. -* Two smart contracts that implement a notion of a cash claim and basic commercial paper (implemented twice, in two - different programming languages). These are simplified versions of the real things. -* Unit tests that check the algorithms do what is expected, and which verify the behaviour of the smart contracts. -* API documentation and tutorials (what you're reading) -* A simple standalone node that uses an embedded message queue broker as its P2P messaging layer. -* A trading demo that runs the node in either a listening/buying mode, or a connecting/selling mode, and swaps some - fake commercial paper assets for some self-issued IOU cash, using a generic *protocol framework*. -* It also includes two oracles: one for precise timestamping and another for interest rate swaps. +* API documentation and tutorials (what you're reading). +* A business process orchestration framework. +* Notary infrastructure for precise timestamping, and elimination of double spending without a blockchain. +* A simple REST API. Some things it does not currently include but should gain later are: * Sandboxing, distribution or publication of smart contract code -* A peer to peer network * Database persistence -* An API for integrating external software * A user interface for administration * Many other things -You can browse `the JIRA bug tracker `_. - The prototype's goal is rapid exploration of ideas. Therefore in places it takes shortcuts that a production system would not in order to boost productivity: * It uses an object graph serialization framework instead of a well specified, vendor neutral protocol. -* It uses secp256r1, an obsolete elliptic curve. * It uses the default, out of the box Apache Artemis MQ protocol instead of AMQP/1.0 (although switching should be easy) +* There is no inter-node SSL or other encryption yet. Contracts --------- The primary goal of this prototype is to implement various kinds of contracts and verify that useful business logic can be expressed with the data model, developing and refining an API along the way. To that end there are currently -two contracts in the repository: +four contracts in the repository: 1. Cash 2. Commercial paper +3. Nettable obligations +4. Interest rate swaps ``Cash`` implements the idea of a claim on some quantity of deposits at some institutional party, denominated in some currency, identified by some *deposit reference*. A deposit reference is an opaque byte array which is usable by @@ -57,12 +57,14 @@ contract is implemented twice, once in Java and once in a language called Kotlin ``InterestRateSwap`` implements a vanilla OTC same currency bilateral fixed / floating leg swap. For further details, see :doc:`irs` +``Obligation`` implements a bilaterally or multi-laterally nettable, fungible obligation that can default. + Each contract comes with unit tests. Kotlin ------ -The prototype is written in a language called `Kotlin `_. Kotlin is a language that targets the JVM +Corda is written in a language called `Kotlin `_. Kotlin is a language that targets the JVM and can be thought of as a simpler Scala, with much better Java interop. It is developed by and has commercial support from JetBrains, the makers of the IntelliJ IDE and other popular developer tools. @@ -71,11 +73,4 @@ Java for industrial use and as such, the syntax was carefully designed to be rea the language, after only a few minutes of introduction. Due to the seamless Java interop the use of Kotlin to extend the platform is *not* required and the tutorial shows how -to write contracts in both Kotlin and Java. You can `read more about why Kotlin is a potentially strong successor to Java here `_. - -Kotlin programs use the regular Java standard library and ordinary Java frameworks. Frameworks used at this time are: - -* JUnit for unit testing -* Kryo for serialisation (this is not intended to be permanent) -* Gradle for the build -* Guava for a few utility functions +to write contracts in both Kotlin and Java. You can `read more about why Kotlin is a potentially strong successor to Java here `_. \ No newline at end of file diff --git a/docs/build/html/_sources/release-notes.txt b/docs/build/html/_sources/release-notes.txt index f8dcde9f73..b78680b575 100644 --- a/docs/build/html/_sources/release-notes.txt +++ b/docs/build/html/_sources/release-notes.txt @@ -6,13 +6,72 @@ Here are brief summaries of what's changed between each snapshot release. Unreleased ---------- -Here are changes in git master that haven't yet made it to a snapshot release: +There are currently no unreleased changes. -* The cash contract has moved from com.r3corda.contracts to com.r3corda.contracts.cash. -* Amount class is now generic, to support non-currency types (such as assets, or currency with additional information). +Milestone 1 +----------- + +Highlights of this release: + +* Event scheduling. States in the ledger can now request protocols to be invoked at particular times, for states + considered relevant by the wallet. +* Upgrades to the notary/consensus service support: + + * There is now a way to change the notary controlling a state. + * You can pick between validating and non-validating notaries, these let you select your privacy/robustness tradeoff. + +* A new obligation contract that supports bilateral and multilateral netting of obligations, default tracking and + more. +* Improvements to the financial type system, with core classes and contracts made more generic. +* Switch to a better digital signature algorithm: ed25519 instead of the previous JDK default of secp256r1. +* A new integration test suite. +* A new Java unit testing DSL for contracts, similar in spirit to the one already developed for Kotlin users (which + depended on Kotlin specific features). +* An experimental module, where developers who want to work with the latest Corda code can check in contracts/cordapp + code before it's been fully reviewed. Code in this module has compiler warnings suppressed but we will still make + sure it compiles across refactorings. +* Persistence improvements: transaction data is now stored to disk and automatic protocol resume is now implemented. +* Many smaller bug fixes, cleanups and improvements. + +We have new documentation on: + +* :doc:`event-scheduling` +* :doc:`transaction-data-types` +* :doc:`consensus` + +Summary of API changes (not exhaustive): + +* Notary/consensus service: + + * ``NotaryService`` is now extensible. + * Every ``ContractState`` now has to specify a *participants* field, which is a list of parties that are able to + consume this state in a valid transaction. This is used for e.g. making sure all relevant parties obtain the updated + state when changing a notary. + * Introduced ``TransactionState``, which wraps ``ContractState``, and is used when defining a transaction output. + The notary field is moved from ``ContractState`` into ``TransactionState``. + * Every transaction now has a *type* field, which specifies custom build & validation rules for that transaction type. + Currently two types are supported: General (runs the default build and validation logic) and NotaryChange ( + contract code is not run during validation, checks that the notary field is the only difference between the + inputs and outputs). + ``TransactionBuilder()`` is now abstract, you should use ``TransactionType.General.Builder()`` for building transactions. + +* The cash contract has moved from ``com.r3corda.contracts`` to ``com.r3corda.contracts.cash`` +* ``Amount`` class is now generic, to support non-currency types such as physical assets. Where you previously had just + ``Amount``, you should now use ``Amount``. * Refactored the Cash contract to have a new FungibleAsset superclass, to model all countable assets that can be merged and split (currency, barrels of oil, etc.) +* Messaging: + * ``addMessageHandler`` now has a different signature as part of error handling changes. + * If you want to return nothing to a protocol, use ``Ack`` instead of ``Unit`` from now on. + +* In the IRS contract, dateOffset is now an integer instead of an enum. +* In contracts, you now use ``tx.getInputs`` and ``tx.getOutputs`` instead of ``getInStates`` and ``getOutStates``. This is + just a renaming. +* A new ``NonEmptySet`` type has been added for cases where you wish to express that you have a collection of unique + objects which cannot be empty. +* Please use the global ``newSecureRandom()`` function rather than instantiating your own SecureRandom's from now on, as + the custom function forces the use of non-blocking random drivers on Linux. Milestone 0 ----------- @@ -24,4 +83,4 @@ This is the first release, which includes: * The first version of the protocol/orchestration framework * Some initial support for pluggable consensus mechanisms * Tutorials and documentation explaining how it works -* Much more ... \ No newline at end of file +* Much more ... diff --git a/docs/build/html/_sources/running-the-demos.txt b/docs/build/html/_sources/running-the-demos.txt index 93499522a5..a064258f66 100644 --- a/docs/build/html/_sources/running-the-demos.txt +++ b/docs/build/html/_sources/running-the-demos.txt @@ -73,9 +73,7 @@ And in the second run: ./build/install/r3prototyping/bin/irsdemo --role=NodeB -The node in the first terminal will complain that it didn't know about nodeB, so restart it. It'll then find the -location and identity keys of nodeA and be happy. NodeB also doubles up as the interest rates oracle and you should -see some rates data get loaded. +NodeB also doubles up as the interest rates oracle and you should see some rates data get loaded. Now in the third terminal run: diff --git a/docs/build/html/_sources/transaction-data-types.txt b/docs/build/html/_sources/transaction-data-types.txt index 20872a7c01..49ea4e2ac8 100644 --- a/docs/build/html/_sources/transaction-data-types.txt +++ b/docs/build/html/_sources/transaction-data-types.txt @@ -1,5 +1,5 @@ -Transaction Data Types -====================== +Data types +========== There is a large library of data types used in Corda transactions and contract state objects. @@ -27,15 +27,18 @@ delivered (themselves referring to a currency), an ``Amount`` such as the follow Amount> -Contract State --------------- +State +----- A Corda contract is composed of three parts; the executable code, the legal prose, and the state objects that represent the details of the contract (see :doc:`data-model` for further detail). States essentially convert the generic template -(code and legal prose) into a specific instance. In a ``WireTransaction``, outputs are provided as ``ContractState`` +(code and legal prose) into a specific instance. In a ``WireTransaction``, outputs are provided as ``TransactionState`` implementations, while the inputs are references to the outputs of a previous transaction. These references are then stored as ``StateRef`` objects, which are converted to ``StateAndRef`` on demand. +The ``TransactionState`` is a container for a ``ContractState`` (the custom data used by a contract program) and additional +platform-level state information, such as the *notary* pointer (see :doc:`consensus`). + A number of interfaces then extend ``ContractState``, representing standardised functionality for states: ``OwnableState`` @@ -64,8 +67,8 @@ interface for its subclasses' state objects to implement. The clear use-case is intended to be readily extensible to cover other assets, for example commodities could be modelled by using a subclass whose state objects include further details (location of the commodity, origin, grade, etc.) as needed. -Transaction Types ------------------ +Transaction lifecycle types +--------------------------- The ``WireTransaction`` class contains the core of a transaction without signatures, and with references to attachments in place of the attachments themselves (see also :doc:`data-model`). Once signed these are encapsulated in the @@ -84,7 +87,7 @@ for signatures present on the transaction, as well as list of parties for those .. note:: These types are provisional and are likely to change in future, for example to add additional information to ``Party``. -Date Support +Date support ------------ There are a number of supporting interfaces and classes for use by contract which deal with dates (especially in the diff --git a/docs/build/html/api/alltypes/index.html b/docs/build/html/api/alltypes/index.html index a61c9e0e8b..4087f54f7b 100644 --- a/docs/build/html/api/alltypes/index.html +++ b/docs/build/html/api/alltypes/index.html @@ -56,8 +56,15 @@ I/O), or a mock implementation suitable for unit test environments.

com.r3corda.protocols.AbstractRequestMessage -

Abstract superclass for request messages sent to services, which includes common -fields such as replyTo and replyToTopic.

+ + + + +protocols.AbstractStateReplacementProtocol + +

Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. +Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these +protocols.

@@ -83,6 +90,14 @@ We dont actually do anything with this yet though, so its ignored for now.

+com.r3corda.core.messaging.Ack + +

A general Ack message that conveys no content other than its presence for use when you want an acknowledgement +from a recipient. Using Unit can be ambiguous as it is similar to Void and so could mean no response.

+ + + + com.r3corda.node.utilities.AddOrRemove

Enum for when adding/removing something, for example adding or removing an entry in a directory.

@@ -105,6 +120,12 @@ for ensuring code runs on the right thread, and also for unit testing.

+com.r3corda.core.testing.AlwaysSucceedContract + + + + + com.r3corda.core.contracts.Amount

Amount represents a positive quantity of some token (currency, asset, etc.), measured in quantity of the smallest @@ -114,6 +135,14 @@ amount used in whatever underlying thing the amount represents.

+com.r3corda.core.protocols.AppContext + +

This is just some way to track what attachments need to be in the class loader, but may later include some app +properties loaded from the attachments. And perhaps the authenticated user for an API call?

+ + + + com.r3corda.node.services.messaging.ArtemisMessagingService

This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product. @@ -124,14 +153,6 @@ as well.

-com.r3corda.contracts.cash.AssetIssuanceDefinition - -

Subset of cash-like contract state, containing the issuance definition. If these definitions match for two -contracts states, those states can be aggregated.

- - - - com.r3corda.core.contracts.Attachment

An attachment is a ZIP (or an optionally signed JAR) that contains one or more files. Attachments are meant to @@ -150,8 +171,7 @@ of how attachments are meant to be used include:

com.r3corda.core.node.services.AttachmentStorage -

An attachment store records potentially large binary objects, identified by their hash. Note that attachments are -immutable and can never be erased once inserted

+

An attachment store records potentially large binary objects, identified by their hash.

@@ -181,6 +201,13 @@ API call from a single party without bi-directional access to the database of of +com.r3corda.core.contracts.BilateralNettableState + +

Interface for state objects that support being netted with other state objects.

+ + + + com.r3corda.core.utilities.BriefLogFormatter

A Java logging formatter that writes more compact output than the default.

@@ -209,7 +236,7 @@ no staff are around to handle problems.

-com.r3corda.contracts.cash.Cash +com.r3corda.contracts.asset.Cash

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour @@ -246,6 +273,19 @@ the same transaction.

+com.r3corda.demos.CliParams + +

Parsed command line parameters.

+ + + + +com.r3corda.demos.CliParamsSpec + + + + + java.time.Clock (extensions in package com.r3corda.node.utilities) @@ -319,7 +359,9 @@ timestamp attached to the transaction itself i.e. it is NOT necessarily the curr

A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk file that the program can use to persist data across transactions. States are immutable: once created they are never -updated, instead, any changes must generate a new successor state.

+updated, instead, any changes must generate a new successor state. States can be updated (consumed) only once: the +notary is responsible for ensuring there is no "double spending" by only signing a transaction if the input states +are all free.

@@ -331,6 +373,12 @@ updated, instead, any changes must generate a new successor state.

+java.util.Currency (extensions in package com.r3corda.core.contracts) + + + + + com.r3corda.node.servlets.DataUploadServlet

Accepts binary streams, finds the right AcceptsFileUpload implementor and hands the stream off to it.

@@ -346,14 +394,6 @@ glue that sits between the network layer and the database layer.

-com.r3corda.core.contracts.DateOffset - -

Date offset that the fixing is done prior to the accrual start date. -Currently not used in the calculation.

- - - - com.r3corda.core.contracts.DateRollConvention

This reflects what happens if a date on which a business event is supposed to happen actually falls upon a non-working day @@ -402,6 +442,13 @@ implementation of general protocols that manipulate many agreement types.

+com.r3corda.core.serialization.DeserializeAsKotlinObjectDef + +

Marker interface for kotlin object definitions so that they are deserialized as the singleton instance.

+ + + + com.r3corda.core.crypto.DigitalSignature

A wrapper around a digital signature. The covering field is a generic tag usable by whatever is interpreting the @@ -429,12 +476,25 @@ building partially signed transactions.

+com.r3corda.core.testing.DummyLinearState + + + + + com.r3corda.core.crypto.DummyPublicKey +com.r3corda.core.contracts.DummyState + +

Dummy state for use in testing. Not part of any real contract.

+ + + + com.r3corda.node.services.keys.E2ETestKeyManagementService

A simple in-memory KMS that doesnt bother saving keys to disk. A real implementation would:

@@ -442,6 +502,20 @@ building partially signed transactions.

+com.r3corda.core.serialization.Ed25519PrivateKeySerializer + +

For serialising an ed25519 private key

+ + + + +com.r3corda.core.serialization.Ed25519PublicKeySerializer + +

For serialising an ed25519 public key

+ + + + com.r3corda.core.utilities.Emoji

A simple wrapper class that contains icons and support for printing them only when were connected to a terminal.

@@ -546,6 +620,14 @@ Assumes that the rate is valid.

+com.r3corda.node.services.FixingSessionInitiationHandler + +

This is a temporary handler required for establishing random sessionIDs for the Fixer and Floater as part of +running scheduled fixings for the InterestRateSwap contract.

+ + + + com.r3corda.contracts.FloatingRate

The parent class of the Floating rate classes

@@ -569,7 +651,7 @@ that would divide into (eg annually = 1, semiannual = 2, monthly = 12 etc).

-com.r3corda.contracts.cash.FungibleAsset +com.r3corda.contracts.asset.FungibleAsset

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States contain assets which are equivalent (such as cash of the same currency), so records of their existence can @@ -581,15 +663,22 @@ countable, and so on.

-com.r3corda.contracts.cash.FungibleAssetState +com.r3corda.contracts.asset.FungibleAssetState

Common elements of cash contract states.

+com.r3corda.demos.IRSDemoNode + + + + + com.r3corda.demos.IRSDemoRole +

Roles. There are 4 modes this demo can be run:

@@ -610,6 +699,12 @@ service would provide.

+com.r3corda.core.protocols.IllegalProtocolLogicException + + + + + com.r3corda.core.serialization.ImmutableClassSerializer

Serializes properties and deserializes by using the constructor. This assumes that all backed properties are @@ -656,7 +751,16 @@ testing).

-com.r3corda.contracts.cash.InsufficientBalanceException +com.r3corda.core.testing.InMemoryWalletService + +

This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

+ + + + +com.r3corda.contracts.asset.InsufficientBalanceException @@ -718,6 +822,21 @@ from which the state object is initialised.

+com.r3corda.core.contracts.IssueCommand + +

A common issue command, to enforce that issue commands have a nonce value.

+ + + + +com.r3corda.core.contracts.Issued + +

Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else thats +quantifiable with integer quantities.

+ + + + kotlin.collections.Iterable (extensions in package com.r3corda.core.contracts) @@ -730,7 +849,32 @@ from which the state object is initialised.

-kotlin.collections.Iterable (extensions in package com.r3corda.contracts.cash) +kotlin.collections.Iterable (extensions in package com.r3corda.contracts.asset) + + + + + +kotlin.collections.Iterable (extensions in package com.r3corda.node.internal.testing) + + + + + +com.r3corda.core.contracts.JavaTestHelpers + + + + + +com.r3corda.core.testing.JavaTestHelpers + +

JAVA INTEROP. Please keep the following points in mind when extending the Kotlin DSL

+ + + + +com.r3corda.contracts.testing.JavaTestHelpers @@ -758,12 +902,29 @@ call out to a hardware security module that enforces various auditing and freque +com.r3corda.core.serialization.KotlinObjectSerializer + +

Serializer to deserialize kotlin object definitions marked with DeserializeAsKotlinObjectDef.

+ + + + com.r3corda.core.testing.LabeledOutput +com.r3corda.core.testing.LastLineShouldTestForAcceptOrFailure + +

If you jumped here from a compiler error make sure the last line of your test tests for a transaction accept or fail +This is a dummy type that can only be instantiated by functions in this module. This way we can ensure that all tests +will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of +the triggered diagnostic

+ + + + com.r3corda.core.contracts.LedgerTransaction

A LedgerTransaction wraps the data needed to calculate one or more successor states from a set of input states. @@ -917,6 +1078,13 @@ This is not an interface because it is too lightweight to bother mocking out.

+com.r3corda.core.contracts.MoveCommand + +

A common move command for contracts which can change owner.

+ + + + com.r3corda.node.utilities.MutableClock

An abstract class with helper methods for a type of Clock that might have its concept of "now" @@ -932,6 +1100,14 @@ adjusted externally.

+com.r3corda.core.contracts.NetType + +

Enum for the types of netting that can be applied to state objects. Exact behaviour +for each type of netting is left to the contract to determine.

+ + + + com.r3corda.core.node.services.NetworkCacheError @@ -1026,11 +1202,18 @@ rate fix (e.g. LIBOR, EURIBOR ...).

+com.r3corda.node.services.events.NodeSchedulerService + +

A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

+ + + + com.r3corda.node.services.wallet.NodeWalletService -

This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

+

Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).

@@ -1038,7 +1221,32 @@ states relevant to us into a database and once such a wallet is implemented, thi com.r3corda.core.utilities.NonEmptySet

A set which is constrained to ensure it can never be empty. An initial value must be provided at -construction, and attempting to remove the last element will cause an IllegalStateException.

+construction, and attempting to remove the last element will cause an IllegalStateException. +The underlying set is exposed for Kryo to access, but should not be accessed directly.

+ + + + +com.r3corda.core.utilities.NonEmptySetSerializer + +

Custom serializer which understands it has to read in an item before +trying to construct the set.

+ + + + +protocols.NotaryChangeProtocol + +

A protocol to be used for changing a states Notary. This is required since all input states to a transaction +must point to the same notary.

+ + + + +com.r3corda.node.services.NotaryChangeService + +

A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

@@ -1074,6 +1282,16 @@ construction, and attempting to remove the last element will cause an IllegalSta +com.r3corda.contracts.asset.Obligation + +

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+ + + + com.r3corda.core.serialization.OpaqueBytes

A simple class that wraps a byte array and makes the equals/hashCode/toString methods work as you actually expect. @@ -1197,6 +1415,20 @@ a node crash, how many instances of your protocol there are running and so on. +com.r3corda.core.protocols.ProtocolLogicRef + +

A class representing a ProtocolLogic instance which would be possible to safely pass out of the contract sandbox

+ + + + +com.r3corda.core.protocols.ProtocolLogicRefFactory + +

A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

+ + + + com.r3corda.node.api.ProtocolRef

Encapsulates the protocol to be instantiated. e.g. TwoPartyTradeProtocol.Buyer.

@@ -1267,6 +1499,13 @@ for each step.

+com.r3corda.core.node.services.ReadOnlyTransactionStorage + +

Thread-safe storage of transactions.

+ + + + com.r3corda.core.utilities.RecordingMap

A RecordingMap wraps a regular Map<K, V> and records the sequence of gets and puts to it. This is useful in @@ -1333,6 +1572,51 @@ again.

+com.r3corda.core.contracts.SchedulableState + + + + + +com.r3corda.core.contracts.Scheduled + +

Something which is scheduled to happen at a point in time

+ + + + +com.r3corda.core.contracts.ScheduledActivity + +

This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

+ + + + +com.r3corda.node.services.events.ScheduledActivityObserver + +

This observes the wallet and schedules and unschedules activities appropriately based on state production and +consumption.

+ + + + +com.r3corda.core.contracts.ScheduledStateRef + +

Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

+ + + + +com.r3corda.core.node.services.SchedulerService + +

Provides access to schedule activity at some point in time. This interface might well be expanded to +increase the feature set in the future.

+ + + + com.r3corda.core.crypto.SecureHash @@ -1399,6 +1683,14 @@ functionality and you dont want to hard-code which types in the interface.

+com.r3corda.protocols.ServiceRequestMessage + +

Abstract superclass for request messages sent to services, which includes common +fields such as replyTo and replyToTopic.

+ + + + com.r3corda.core.node.services.ServiceType

Identifier for service types a node can expose over the network to other peers. These types are placed into network @@ -1497,6 +1789,19 @@ transaction defined the state and where in that transaction it was.

+protocols.StateReplacementException + + + + + +protocols.StateReplacementRefused + +

Thrown when a participant refuses proposed the state replacement

+ + + + com.r3corda.node.api.StatesQuery

Extremely rudimentary query language which should most likely be replaced with a product

@@ -1567,6 +1872,13 @@ way that ensures itll be released if theres an exception.

+com.r3corda.core.utilities.TimeWindow + +

A class representing a window in time from a particular instant, lasting a specified duration.

+ + + + com.r3corda.core.node.services.TimestampChecker

Checks if the given timestamp falls within the allowed tolerance interval

@@ -1597,18 +1909,6 @@ then B and C trade with each other, then C and A etc).

-com.r3corda.demos.TraderDemoProtocolBuyer - - - - - -com.r3corda.demos.TraderDemoProtocolSeller - - - - - com.r3corda.node.api.TransactionBuildStep

Encapsulate a generateXXX method call on a contract.

@@ -1619,9 +1919,8 @@ then B and C trade with each other, then C and A etc).

com.r3corda.core.contracts.TransactionBuilder

A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is -intended to be passed around contracts that may edit it by adding new states/commands or modifying the existing set. -Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from -multiple parties.

+intended to be passed around contracts that may edit it by adding new states/commands. Then once the states +and commands are right, this class can be used as a holding bucket to gather signatures from multiple parties.

@@ -1632,6 +1931,14 @@ multiple parties.

+com.r3corda.core.contracts.TransactionForContract + +

A transaction to be passed as input to a contract verification function. Defines helper methods to +simplify verification logic in contracts.

+ + + + com.r3corda.core.testing.TransactionForTest @@ -1674,6 +1981,14 @@ this subgraph does not contain conflicts and is accepted by the involved contrac +com.r3corda.core.contracts.TransactionState + +

A wrapper for ContractState containing additional platform-level state information. +This is the definitive state that is stored on the ledger and used in transaction outputs.

+ + + + com.r3corda.core.node.services.TransactionStorage

Thread-safe storage of transactions.

@@ -1681,6 +1996,13 @@ this subgraph does not contain conflicts and is accepted by the involved contrac +com.r3corda.core.contracts.TransactionType + +

Defines transaction build & validation logic for a specific transaction type

+ + + + com.r3corda.core.contracts.TransactionVerificationException @@ -1711,6 +2033,13 @@ and seller) and the following steps:

+com.r3corda.core.node.services.TxWritableStorageService + +

Storage service, with extensions to allow validated transactions to be added to. For use only within ServiceHub.

+ + + + com.r3corda.core.contracts.TypeOnlyCommandData

Commands that inherit from this are intended to have no data items: its only their presence that matters.

@@ -1749,8 +2078,7 @@ first. The wrapper helps you to avoid forgetting this vital step. Things you mig com.r3corda.demos.protocols.UpdateBusinessDayProtocol -

This is a very temporary, demo-oriented way of initiating processing of temporal events and is not -intended as the way things will necessarily be done longer term

+

This is a less temporary, demo-oriented way of initiating processing of temporal events

@@ -1782,22 +2110,6 @@ about new transactions from our peers and generate new transactions that consume -com.r3corda.node.internal.testing.WalletFiller - - - - - -com.r3corda.node.services.wallet.WalletImpl - -

A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, -because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to -change out from underneath you, even though the canonical currently-best-known wallet may change as we learn -about new transactions from our peers and generate new transactions that consume states ourselves.

- - - - com.r3corda.core.node.services.WalletService

A WalletService is responsible for securely and safely persisting the current state of a wallet to storage. The diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html b/docs/build/html/api/com.r3corda.contracts.asset/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html new file mode 100644 index 0000000000..663d79fe8f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html @@ -0,0 +1,15 @@ + + +CASH_PROGRAM_ID - + + + +com.r3corda.contracts.asset / CASH_PROGRAM_ID
+
+

CASH_PROGRAM_ID

+ +val CASH_PROGRAM_ID: Cash
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/-init-.html new file mode 100644 index 0000000000..9d2bb595b7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/-init-.html @@ -0,0 +1,16 @@ + + +Cash.Commands.Exit.<init> - + + + +com.r3corda.contracts.asset / Cash / Commands / Exit / <init>
+
+

<init>

+Exit(amount: Amount<Issued<Currency>>)
+

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/amount.html new file mode 100644 index 0000000000..422f093494 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/amount.html @@ -0,0 +1,16 @@ + + +Cash.Commands.Exit.amount - + + + +com.r3corda.contracts.asset / Cash / Commands / Exit / amount
+
+

amount

+ +val amount: Amount<Issued<Currency>>
+Overrides Exit.amount
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/index.html new file mode 100644 index 0000000000..b94696ccd6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-exit/index.html @@ -0,0 +1,40 @@ + + +Cash.Commands.Exit - + + + +com.r3corda.contracts.asset / Cash / Commands / Exit
+
+

Exit

+data class Exit : Commands, Exit<Currency>
+

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+
+

Constructors

+ + + + + + + +
+<init> +Exit(amount: Amount<Issued<Currency>>)

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+

Properties

+ + + + + + + +
+amount +val amount: Amount<Issued<Currency>>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/-init-.html new file mode 100644 index 0000000000..4f6712998b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/-init-.html @@ -0,0 +1,16 @@ + + +Cash.Commands.Issue.<init> - + + + +com.r3corda.contracts.asset / Cash / Commands / Issue / <init>
+
+

<init>

+Issue(nonce: Long = newSecureRandom().nextLong())
+

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/index.html new file mode 100644 index 0000000000..ae387254ae --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/index.html @@ -0,0 +1,40 @@ + + +Cash.Commands.Issue - + + + +com.r3corda.contracts.asset / Cash / Commands / Issue
+
+

Issue

+data class Issue : Issue, Commands
+

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+
+

Constructors

+ + + + + + + +
+<init> +Issue(nonce: Long = newSecureRandom().nextLong())

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+

Properties

+ + + + + + + +
+nonce +val nonce: Long
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/nonce.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/nonce.html new file mode 100644 index 0000000000..95a9822b02 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-issue/nonce.html @@ -0,0 +1,16 @@ + + +Cash.Commands.Issue.nonce - + + + +com.r3corda.contracts.asset / Cash / Commands / Issue / nonce
+
+

nonce

+ +val nonce: Long
+Overrides IssueCommand.nonce
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/-init-.html new file mode 100644 index 0000000000..e2e384ed92 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/-init-.html @@ -0,0 +1,20 @@ + + +Cash.Commands.Move.<init> - + + + +com.r3corda.contracts.asset / Cash / Commands / Move / <init>
+
+

<init>

+Move(contractHash: SecureHash? = null)
+

A command stating that money has been moved, optionally to fulfil another contract.

+

Parameters

+ +contractHash - the contract this move is for the attention of. Only that contracts verify function +should take the moved states into account when considering whether it is valid. Typically this will be +null.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/contract-hash.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/contract-hash.html new file mode 100644 index 0000000000..59d46a8707 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/contract-hash.html @@ -0,0 +1,18 @@ + + +Cash.Commands.Move.contractHash - + + + +com.r3corda.contracts.asset / Cash / Commands / Move / contractHash
+
+

contractHash

+ +val contractHash: SecureHash?
+Overrides MoveCommand.contractHash
+

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/index.html new file mode 100644 index 0000000000..11985568ed --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/-move/index.html @@ -0,0 +1,45 @@ + + +Cash.Commands.Move - + + + +com.r3corda.contracts.asset / Cash / Commands / Move
+
+

Move

+data class Move : Move, Commands
+

A command stating that money has been moved, optionally to fulfil another contract.

+

Parameters

+ +contractHash - the contract this move is for the attention of. Only that contracts verify function +should take the moved states into account when considering whether it is valid. Typically this will be +null.
+
+
+

Constructors

+ + + + + + + +
+<init> +Move(contractHash: SecureHash? = null)

A command stating that money has been moved, optionally to fulfil another contract.

+
+

Properties

+ + + + + + + +
+contractHash +val contractHash: SecureHash?

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/index.html new file mode 100644 index 0000000000..46bf5ea78c --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-commands/index.html @@ -0,0 +1,70 @@ + + +Cash.Commands - + + + +com.r3corda.contracts.asset / Cash / Commands
+
+

Commands

+interface Commands : CommandData
+
+
+

Types

+ + + + + + + + + + + + + + + +
+Exit +data class Exit : Commands, Exit<Currency>

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+Issue +data class Issue : Issue, Commands

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+Move +data class Move : Move, Commands

A command stating that money has been moved, optionally to fulfil another contract.

+
+

Inheritors

+ + + + + + + + + + + + + + + +
+Exit +data class Exit : Commands, Exit<Currency>

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+Issue +data class Issue : Issue, Commands

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+Move +data class Move : Move, Commands

A command stating that money has been moved, optionally to fulfil another contract.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-init-.html new file mode 100644 index 0000000000..c8ee015072 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-init-.html @@ -0,0 +1,25 @@ + + +Cash.<init> - + + + +com.r3corda.contracts.asset / Cash / <init>
+
+

<init>

+Cash()
+

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour +(a blend of issuer+depositRef) and you couldnt merge outputs of two colours together, but you COULD put them in +the same transaction.

+

The goal of this design is to ensure that money can be withdrawn from the ledger easily: if you receive some money +via this contract, you always know where to go in order to extract it from the R3 ledger, no matter how many hands +it has passed through in the intervening time.

+

At the same time, other contracts that just want money and dont care much who is currently holding it in their +vaults can ignore the issuer/depositRefs and just examine the amount fields.

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/-init-.html new file mode 100644 index 0000000000..e51cfe241a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/-init-.html @@ -0,0 +1,18 @@ + + +Cash.State.<init> - + + + +com.r3corda.contracts.asset / Cash / State / <init>
+
+

<init>

+State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey)
+
+
+State(amount: Amount<Issued<Currency>>, owner: PublicKey)
+

A state representing a cash claim against some party

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/amount.html new file mode 100644 index 0000000000..d95375d7f4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/amount.html @@ -0,0 +1,16 @@ + + +Cash.State.amount - + + + +com.r3corda.contracts.asset / Cash / State / amount
+
+

amount

+ +val amount: Amount<Issued<Currency>>
+Overrides State.amount
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/contract.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/contract.html new file mode 100644 index 0000000000..6ec51867f3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/contract.html @@ -0,0 +1,43 @@ + + +Cash.State.contract - + + + +com.r3corda.contracts.asset / Cash / State / contract
+
+

contract

+ +val contract: Cash
+Overrides ContractState.contract
+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/deposit.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/deposit.html new file mode 100644 index 0000000000..b05b967fc6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/deposit.html @@ -0,0 +1,20 @@ + + +Cash.State.deposit - + + + +com.r3corda.contracts.asset / Cash / State / deposit
+
+

deposit

+ +val deposit: PartyAndReference
+Overrides State.deposit
+

Where the underlying currency backing this ledger entry can be found (propagated)

+

Getter
+

Where the underlying currency backing this ledger entry can be found (propagated)

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/index.html new file mode 100644 index 0000000000..84f1bcfab9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/index.html @@ -0,0 +1,132 @@ + + +Cash.State - + + + +com.r3corda.contracts.asset / Cash / State
+
+

State

+data class State : State<Currency>
+

A state representing a cash claim against some party

+
+
+

Constructors

+ + + + + + + +
+<init> +State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey)State(amount: Amount<Issued<Currency>>, owner: PublicKey)

A state representing a cash claim against some party

+
+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+amount +val amount: Amount<Issued<Currency>>
+contract +val contract: Cash

An instance of the contract class that will verify this state.

+
+deposit +val deposit: PartyAndReference

Where the underlying currency backing this ledger entry can be found (propagated)

+
+issuanceDef +val issuanceDef: Issued<Currency>
+owner +val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+
+participants +val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+productAmount +val productAmount: Amount<Currency>
+

Functions

+ + + + + + + + + + + + + + + +
+move +fun move(newAmount: Amount<Currency>, newOwner: PublicKey): State<Currency>
+toString +fun toString(): String
+withNewOwner +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+

Extension Functions

+ + + + + + + + + + + + + + + + + + + +
+issued by +infix fun State.issued by(party: Party): State
+infix fun State.issued by(deposit: PartyAndReference): State
+owned by +infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
+with deposit +infix fun State.with deposit(deposit: PartyAndReference): State
+with notary +infix fun State.with notary(notary: Party): TransactionState<State>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/issuance-def.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/issuance-def.html new file mode 100644 index 0000000000..53ff2162c2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/issuance-def.html @@ -0,0 +1,16 @@ + + +Cash.State.issuanceDef - + + + +com.r3corda.contracts.asset / Cash / State / issuanceDef
+
+

issuanceDef

+ +val issuanceDef: Issued<Currency>
+Overrides FungibleAssetState.issuanceDef
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/move.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/move.html new file mode 100644 index 0000000000..f37e259715 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/move.html @@ -0,0 +1,15 @@ + + +Cash.State.move - + + + +com.r3corda.contracts.asset / Cash / State / move
+
+

move

+ +fun move(newAmount: Amount<Currency>, newOwner: PublicKey): State<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/owner.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/owner.html new file mode 100644 index 0000000000..60b915aa35 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/owner.html @@ -0,0 +1,17 @@ + + +Cash.State.owner - + + + +com.r3corda.contracts.asset / Cash / State / owner
+
+

owner

+ +val owner: PublicKey
+Overrides State.owner
+

There must be a MoveCommand signed by this key to claim the amount

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/participants.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/participants.html new file mode 100644 index 0000000000..89388968a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/participants.html @@ -0,0 +1,34 @@ + + +Cash.State.participants - + + + +com.r3corda.contracts.asset / Cash / State / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/product-amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/product-amount.html new file mode 100644 index 0000000000..d8c5d61ac8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/product-amount.html @@ -0,0 +1,16 @@ + + +Cash.State.productAmount - + + + +com.r3corda.contracts.asset / Cash / State / productAmount
+
+

productAmount

+ +val productAmount: Amount<Currency>
+Overrides FungibleAssetState.productAmount
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/to-string.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/to-string.html new file mode 100644 index 0000000000..94c2abeecd --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/to-string.html @@ -0,0 +1,15 @@ + + +Cash.State.toString - + + + +com.r3corda.contracts.asset / Cash / State / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/with-new-owner.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/with-new-owner.html new file mode 100644 index 0000000000..d0fdf7138e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/with-new-owner.html @@ -0,0 +1,17 @@ + + +Cash.State.withNewOwner - + + + +com.r3corda.contracts.asset / Cash / State / withNewOwner
+
+

withNewOwner

+ +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
+Overrides OwnableState.withNewOwner
+

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-issue.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-issue.html new file mode 100644 index 0000000000..bacf9b9dfb --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-issue.html @@ -0,0 +1,21 @@ + + +Cash.generateIssue - + + + +com.r3corda.contracts.asset / Cash / generateIssue
+
+

generateIssue

+ +fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit
+

Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.

+
+
+ +fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: PublicKey, notary: Party): Unit
+

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-spend.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-spend.html new file mode 100644 index 0000000000..08553e2510 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/generate-spend.html @@ -0,0 +1,28 @@ + + +Cash.generateSpend - + + + +com.r3corda.contracts.asset / Cash / generateSpend
+
+

generateSpend

+ +fun generateSpend(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, to: PublicKey, cashStates: List<StateAndRef<State>>): List<PublicKey>
+

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. +Note that the wallet list is not updated: its up to you to do that.

+
+
+ +fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>
+

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. +Note that the wallet list is not updated: its up to you to do that.

+

Parameters

+ +onlyFromParties - if non-null, the wallet will be filtered to only include cash states issued by the set +of given parties. This can be useful if the party youre trying to pay has expectations +about which type of cash claims they are willing to accept.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/index.html new file mode 100644 index 0000000000..21856c02b0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/index.html @@ -0,0 +1,104 @@ + + +Cash - + + + +com.r3corda.contracts.asset / Cash
+
+

Cash

+class Cash : FungibleAsset<Currency>
+

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour +(a blend of issuer+depositRef) and you couldnt merge outputs of two colours together, but you COULD put them in +the same transaction.

+

The goal of this design is to ensure that money can be withdrawn from the ledger easily: if you receive some money +via this contract, you always know where to go in order to extract it from the R3 ledger, no matter how many hands +it has passed through in the intervening time.

+

At the same time, other contracts that just want money and dont care much who is currently holding it in their +vaults can ignore the issuer/depositRefs and just examine the amount fields.

+
+
+
+
+

Types

+ + + + + + + + + + + +
+Commands +interface Commands : CommandData
+State +data class State : State<Currency>

A state representing a cash claim against some party

+
+

Constructors

+ + + + + + + +
+<init> +Cash()

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour +(a blend of issuer+depositRef) and you couldnt merge outputs of two colours together, but you COULD put them in +the same transaction.

+
+

Properties

+ + + + + + + +
+legalContractReference +val legalContractReference: SecureHash

TODO:

+
+

Functions

+ + + + + + + + + + + +
+generateIssue +fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.

+fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

+
+generateSpend +fun generateSpend(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, to: PublicKey, cashStates: List<StateAndRef<State>>): List<PublicKey>
+fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. +Note that the wallet list is not updated: its up to you to do that.

+
+

Inherited Functions

+ + + + + + + +
+verify +open fun verify(tx: TransactionForContract): Unit

This is the function EVERYONE runs

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/legal-contract-reference.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/legal-contract-reference.html new file mode 100644 index 0000000000..5978af553b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/legal-contract-reference.html @@ -0,0 +1,25 @@ + + +Cash.legalContractReference - + + + +com.r3corda.contracts.asset / Cash / legalContractReference
+
+

legalContractReference

+ +val legalContractReference: SecureHash
+Overrides Contract.legalContractReference
+

TODO:

+
  1. hash should be of the contents, not the URI

    +
  2. allow the content to be specified at time of instance creation?

    +

Motivation: its the difference between a state object referencing a programRef, which references a +legalContractReference and a state object which directly references both. The latter allows the legal wording +to evolve without requiring code changes. But creates a risk that users create objects governed by a program +that is inconsistent with the legal contract

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/index.html new file mode 100644 index 0000000000..ecd1941e58 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/index.html @@ -0,0 +1,106 @@ + + +FungibleAssetState - + + + +com.r3corda.contracts.asset / FungibleAssetState
+
+

FungibleAssetState

+interface FungibleAssetState<T, I> : OwnableState
+

Common elements of cash contract states.

+
+
+

Properties

+ + + + + + + + + + + +
+issuanceDef +abstract val issuanceDef: I
+productAmount +abstract val productAmount: Amount<T>
+

Inherited Properties

+ + + + + + + +
+owner +abstract val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+
+

Functions

+ + + + + + + +
+move +abstract fun move(newAmount: Amount<T>, newOwner: PublicKey): FungibleAssetState<T, I>
+

Inherited Functions

+ + + + + + + +
+withNewOwner +abstract fun withNewOwner(newOwner: PublicKey): <ERROR CLASS><CommandData, OwnableState>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+

Extension Functions

+ + + + + + + + + + + +
+hash +fun ContractState.hash(): SecureHash

Returns the SHA-256 hash of the serialised contents of this state (not cached)

+
+with notary +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
+

Inheritors

+ + + + + + + + + + + +
+State +interface State<T> : FungibleAssetState<T, Issued<T>>

A state representing a cash claim against some party

+
+State +data class State<P> : FungibleAssetState<P, IssuanceDefinition<P>>, BilateralNettableState<State<P>>

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/issuance-def.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/issuance-def.html new file mode 100644 index 0000000000..40ec6c2a50 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/issuance-def.html @@ -0,0 +1,15 @@ + + +FungibleAssetState.issuanceDef - + + + +com.r3corda.contracts.asset / FungibleAssetState / issuanceDef
+
+

issuanceDef

+ +abstract val issuanceDef: I
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/move.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/move.html new file mode 100644 index 0000000000..bd9d2983b6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/move.html @@ -0,0 +1,15 @@ + + +FungibleAssetState.move - + + + +com.r3corda.contracts.asset / FungibleAssetState / move
+
+

move

+ +abstract fun move(newAmount: Amount<T>, newOwner: PublicKey): FungibleAssetState<T, I>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/product-amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/product-amount.html new file mode 100644 index 0000000000..c0a2c8926e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset-state/product-amount.html @@ -0,0 +1,15 @@ + + +FungibleAssetState.productAmount - + + + +com.r3corda.contracts.asset / FungibleAssetState / productAmount
+
+

productAmount

+ +abstract val productAmount: Amount<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/amount.html new file mode 100644 index 0000000000..26fe2ecacc --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/amount.html @@ -0,0 +1,15 @@ + + +FungibleAsset.Commands.Exit.amount - + + + +com.r3corda.contracts.asset / FungibleAsset / Commands / Exit / amount
+
+

amount

+ +abstract val amount: Amount<Issued<T>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/index.html new file mode 100644 index 0000000000..3e7b437c8e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-exit/index.html @@ -0,0 +1,40 @@ + + +FungibleAsset.Commands.Exit - + + + +com.r3corda.contracts.asset / FungibleAsset / Commands / Exit
+
+

Exit

+interface Exit<T> : Commands
+

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+
+

Properties

+ + + + + + + +
+amount +abstract val amount: Amount<Issued<T>>
+

Inheritors

+ + + + + + + +
+Exit +data class Exit : Commands, Exit<Currency>

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-issue.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-issue.html new file mode 100644 index 0000000000..8d374c58e4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-issue.html @@ -0,0 +1,40 @@ + + +FungibleAsset.Commands.Issue - + + + +com.r3corda.contracts.asset / FungibleAsset / Commands / Issue
+
+

Issue

+interface Issue : IssueCommand, Commands
+

Allows new asset states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+
+

Inherited Properties

+ + + + + + + +
+nonce +abstract val nonce: Long
+

Inheritors

+ + + + + + + +
+Issue +data class Issue : Issue, Commands

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-move.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-move.html new file mode 100644 index 0000000000..dad666b735 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-move.html @@ -0,0 +1,39 @@ + + +FungibleAsset.Commands.Move - + + + +com.r3corda.contracts.asset / FungibleAsset / Commands / Move
+
+

Move

+interface Move : MoveCommand, Commands
+
+
+

Inherited Properties

+ + + + + + + +
+contractHash +abstract val contractHash: SecureHash?

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+

Inheritors

+ + + + + + + +
+Move +data class Move : Move, Commands

A command stating that money has been moved, optionally to fulfil another contract.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/index.html new file mode 100644 index 0000000000..bf2dcae3d5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/index.html @@ -0,0 +1,68 @@ + + +FungibleAsset.Commands - + + + +com.r3corda.contracts.asset / FungibleAsset / Commands
+
+

Commands

+interface Commands : CommandData
+
+
+

Types

+ + + + + + + + + + + + + + + +
+Exit +interface Exit<T> : Commands

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+Issue +interface Issue : IssueCommand, Commands

Allows new asset states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+Move +interface Move : MoveCommand, Commands
+

Inheritors

+ + + + + + + + + + + + + + + +
+Exit +interface Exit<T> : Commands

A command stating that money has been withdrawn from the shared ledger and is now accounted for +in some other way.

+
+Issue +interface Issue : IssueCommand, Commands

Allows new asset states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+Move +interface Move : MoveCommand, Commands
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-init-.html new file mode 100644 index 0000000000..0058e07544 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-init-.html @@ -0,0 +1,27 @@ + + +FungibleAsset.<init> - + + + +com.r3corda.contracts.asset / FungibleAsset / <init>
+
+

<init>

+FungibleAsset()
+

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States +contain assets which are equivalent (such as cash of the same currency), so records of their existence can +be merged or split as needed where the issuer is the same. For instance, dollars issued by the Fed are fungible and +countable (in cents), barrels of West Texas crude are fungible and countable (oil from two small containers +can be poured into one large container), shares of the same class in a specific company are fungible and +countable, and so on.

+

See Cash for an example subclass that implements currency.

+
+
+

Parameters

+ +T - a type that represents the asset in question. This should describe the basic type of the asset +(GBP, USD, oil, shares in company , etc.) and any additional metadata (issuer, grade, class, etc.)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/amount.html new file mode 100644 index 0000000000..dab9d811f9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/amount.html @@ -0,0 +1,15 @@ + + +FungibleAsset.State.amount - + + + +com.r3corda.contracts.asset / FungibleAsset / State / amount
+
+

amount

+ +abstract val amount: Amount<Issued<T>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/deposit.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/deposit.html new file mode 100644 index 0000000000..edc5d0b5c7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/deposit.html @@ -0,0 +1,16 @@ + + +FungibleAsset.State.deposit - + + + +com.r3corda.contracts.asset / FungibleAsset / State / deposit
+
+

deposit

+ +abstract val deposit: PartyAndReference
+

Where the underlying currency backing this ledger entry can be found (propagated)

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/index.html new file mode 100644 index 0000000000..53a1c27a3a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/index.html @@ -0,0 +1,69 @@ + + +FungibleAsset.State - + + + +com.r3corda.contracts.asset / FungibleAsset / State
+
+

State

+interface State<T> : FungibleAssetState<T, Issued<T>>
+

A state representing a cash claim against some party

+
+
+

Properties

+ + + + + + + + + + + + + + + +
+amount +abstract val amount: Amount<Issued<T>>
+deposit +abstract val deposit: PartyAndReference

Where the underlying currency backing this ledger entry can be found (propagated)

+
+owner +abstract val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+
+

Inherited Properties

+ + + + + + + + + + + +
+issuanceDef +abstract val issuanceDef: I
+productAmount +abstract val productAmount: Amount<T>
+

Inheritors

+ + + + + + + +
+State +data class State : State<Currency>

A state representing a cash claim against some party

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/owner.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/owner.html new file mode 100644 index 0000000000..65b4b0cd45 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-state/owner.html @@ -0,0 +1,17 @@ + + +FungibleAsset.State.owner - + + + +com.r3corda.contracts.asset / FungibleAsset / State / owner
+
+

owner

+ +abstract val owner: PublicKey
+Overrides OwnableState.owner
+

There must be a MoveCommand signed by this key to claim the amount

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/index.html new file mode 100644 index 0000000000..38bb29c219 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/index.html @@ -0,0 +1,102 @@ + + +FungibleAsset - + + + +com.r3corda.contracts.asset / FungibleAsset
+
+

FungibleAsset

+abstract class FungibleAsset<T> : Contract
+

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States +contain assets which are equivalent (such as cash of the same currency), so records of their existence can +be merged or split as needed where the issuer is the same. For instance, dollars issued by the Fed are fungible and +countable (in cents), barrels of West Texas crude are fungible and countable (oil from two small containers +can be poured into one large container), shares of the same class in a specific company are fungible and +countable, and so on.

+

See Cash for an example subclass that implements currency.

+
+
+

Parameters

+ +T - a type that represents the asset in question. This should describe the basic type of the asset +(GBP, USD, oil, shares in company , etc.) and any additional metadata (issuer, grade, class, etc.)
+
+
+

Types

+ + + + + + + + + + + +
+Commands +interface Commands : CommandData
+State +interface State<T> : FungibleAssetState<T, Issued<T>>

A state representing a cash claim against some party

+
+

Constructors

+ + + + + + + +
+<init> +FungibleAsset()

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States +contain assets which are equivalent (such as cash of the same currency), so records of their existence can +be merged or split as needed where the issuer is the same. For instance, dollars issued by the Fed are fungible and +countable (in cents), barrels of West Texas crude are fungible and countable (oil from two small containers +can be poured into one large container), shares of the same class in a specific company are fungible and +countable, and so on.

+
+

Inherited Properties

+ + + + + + + +
+legalContractReference +abstract val legalContractReference: SecureHash

Unparsed reference to the natural language contract that this code is supposed to express (usually a hash of +the contracts contents).

+
+

Functions

+ + + + + + + +
+verify +open fun verify(tx: TransactionForContract): Unit

This is the function EVERYONE runs

+
+

Inheritors

+ + + + + + + +
+Cash +class Cash : FungibleAsset<Currency>

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour +(a blend of issuer+depositRef) and you couldnt merge outputs of two colours together, but you COULD put them in +the same transaction.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/verify.html new file mode 100644 index 0000000000..fff6e7005b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/verify.html @@ -0,0 +1,17 @@ + + +FungibleAsset.verify - + + + +com.r3corda.contracts.asset / FungibleAsset / verify
+
+

verify

+ +open fun verify(tx: TransactionForContract): Unit
+Overrides Contract.verify
+

This is the function EVERYONE runs

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/-init-.html new file mode 100644 index 0000000000..38477e2855 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/-init-.html @@ -0,0 +1,14 @@ + + +InsufficientBalanceException.<init> - + + + +com.r3corda.contracts.asset / InsufficientBalanceException / <init>
+
+

<init>

+InsufficientBalanceException(amountMissing: Amount<Currency>)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/amount-missing.html b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/amount-missing.html new file mode 100644 index 0000000000..749da1ee5d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/amount-missing.html @@ -0,0 +1,15 @@ + + +InsufficientBalanceException.amountMissing - + + + +com.r3corda.contracts.asset / InsufficientBalanceException / amountMissing
+
+

amountMissing

+ +val amountMissing: Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/index.html new file mode 100644 index 0000000000..8031d756a4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-insufficient-balance-exception/index.html @@ -0,0 +1,36 @@ + + +InsufficientBalanceException - + + + +com.r3corda.contracts.asset / InsufficientBalanceException
+
+

InsufficientBalanceException

+class InsufficientBalanceException : Exception
+
+
+

Constructors

+ + + + + + + +
+<init> +InsufficientBalanceException(amountMissing: Amount<Currency>)
+

Properties

+ + + + + + + +
+amountMissing +val amountMissing: Amount<Currency>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-o-b-l-i-g-a-t-i-o-n_-p-r-o-g-r-a-m_-i-d.html b/docs/build/html/api/com.r3corda.contracts.asset/-o-b-l-i-g-a-t-i-o-n_-p-r-o-g-r-a-m_-i-d.html new file mode 100644 index 0000000000..67a47ab10a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-o-b-l-i-g-a-t-i-o-n_-p-r-o-g-r-a-m_-i-d.html @@ -0,0 +1,15 @@ + + +OBLIGATION_PROGRAM_ID - + + + +com.r3corda.contracts.asset / OBLIGATION_PROGRAM_ID
+
+

OBLIGATION_PROGRAM_ID

+ +val OBLIGATION_PROGRAM_ID: Obligation<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/-init-.html new file mode 100644 index 0000000000..af18f3f409 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/-init-.html @@ -0,0 +1,17 @@ + + +Obligation.BilateralNetState.<init> - + + + +com.r3corda.contracts.asset / Obligation / BilateralNetState / <init>
+
+

<init>

+BilateralNetState(partyKeys: Set<PublicKey>, template: StateTemplate<P>)
+

Subset of state, containing the elements which must match for two obligation transactions to be nettable. +If two obligation state objects produce equal bilateral net states, they are considered safe to net directly. +Bilateral states are used in close-out netting.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/index.html new file mode 100644 index 0000000000..5fa4936ec5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/index.html @@ -0,0 +1,48 @@ + + +Obligation.BilateralNetState - + + + +com.r3corda.contracts.asset / Obligation / BilateralNetState
+
+

BilateralNetState

+data class BilateralNetState<P> : NetState<P>
+

Subset of state, containing the elements which must match for two obligation transactions to be nettable. +If two obligation state objects produce equal bilateral net states, they are considered safe to net directly. +Bilateral states are used in close-out netting.

+
+
+

Constructors

+ + + + + + + +
+<init> +BilateralNetState(partyKeys: Set<PublicKey>, template: StateTemplate<P>)

Subset of state, containing the elements which must match for two obligation transactions to be nettable. +If two obligation state objects produce equal bilateral net states, they are considered safe to net directly. +Bilateral states are used in close-out netting.

+
+

Properties

+ + + + + + + + + + + +
+partyKeys +val partyKeys: Set<PublicKey>
+template +val template: StateTemplate<P>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/party-keys.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/party-keys.html new file mode 100644 index 0000000000..2ddd5e694a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/party-keys.html @@ -0,0 +1,15 @@ + + +Obligation.BilateralNetState.partyKeys - + + + +com.r3corda.contracts.asset / Obligation / BilateralNetState / partyKeys
+
+

partyKeys

+ +val partyKeys: Set<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/template.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/template.html new file mode 100644 index 0000000000..de87ee09e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-bilateral-net-state/template.html @@ -0,0 +1,16 @@ + + +Obligation.BilateralNetState.template - + + + +com.r3corda.contracts.asset / Obligation / BilateralNetState / template
+
+

template

+ +val template: StateTemplate<P>
+Overrides NetState.template
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/-init-.html new file mode 100644 index 0000000000..3dbefa121d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/-init-.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Exit.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / Exit / <init>
+
+

<init>

+Exit(aggregateState: IssuanceDefinition<P>, amount: Amount<P>)
+

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/aggregate-state.html new file mode 100644 index 0000000000..ed4ddfe019 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/aggregate-state.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Exit.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / Commands / Exit / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+Overrides IssuanceCommands.aggregateState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/amount.html new file mode 100644 index 0000000000..da43c51824 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/amount.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.Exit.amount - + + + +com.r3corda.contracts.asset / Obligation / Commands / Exit / amount
+
+

amount

+ +val amount: Amount<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/index.html new file mode 100644 index 0000000000..2f9da3e0a9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-exit/index.html @@ -0,0 +1,46 @@ + + +Obligation.Commands.Exit - + + + +com.r3corda.contracts.asset / Obligation / Commands / Exit
+
+

Exit

+data class Exit<P> : Commands, IssuanceCommands<P>
+

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+
+

Constructors

+ + + + + + + +
+<init> +Exit(aggregateState: IssuanceDefinition<P>, amount: Amount<P>)

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+

Properties

+ + + + + + + + + + + +
+aggregateState +val aggregateState: IssuanceDefinition<P>
+amount +val amount: Amount<P>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/-init-.html new file mode 100644 index 0000000000..38b84a837d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/-init-.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Issue.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / Issue / <init>
+
+

<init>

+Issue(aggregateState: IssuanceDefinition<P>, nonce: Long = random63BitValue())
+

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/aggregate-state.html new file mode 100644 index 0000000000..7897792325 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/aggregate-state.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Issue.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / Commands / Issue / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+Overrides IssuanceCommands.aggregateState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/index.html new file mode 100644 index 0000000000..3fe4166ddd --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/index.html @@ -0,0 +1,46 @@ + + +Obligation.Commands.Issue - + + + +com.r3corda.contracts.asset / Obligation / Commands / Issue
+
+

Issue

+data class Issue<P> : Commands, IssuanceCommands<P>
+

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+
+

Constructors

+ + + + + + + +
+<init> +Issue(aggregateState: IssuanceDefinition<P>, nonce: Long = random63BitValue())

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+

Properties

+ + + + + + + + + + + +
+aggregateState +val aggregateState: IssuanceDefinition<P>
+nonce +val nonce: Long
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/nonce.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/nonce.html new file mode 100644 index 0000000000..a25bbd3e38 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-issue/nonce.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.Issue.nonce - + + + +com.r3corda.contracts.asset / Obligation / Commands / Issue / nonce
+
+

nonce

+ +val nonce: Long
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/-init-.html new file mode 100644 index 0000000000..afb8d0650c --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/-init-.html @@ -0,0 +1,20 @@ + + +Obligation.Commands.Move.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / Move / <init>
+
+

<init>

+Move(aggregateState: IssuanceDefinition<P>, contractHash: SecureHash? = null)
+

A command stating that a debt has been moved, optionally to fulfil another contract.

+

Parameters

+ +contractHash - the contract this move is for the attention of. Only that contracts verify function +should take the moved states into account when considering whether it is valid. Typically this will be +null.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/aggregate-state.html new file mode 100644 index 0000000000..596ef6fcdb --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/aggregate-state.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Move.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / Commands / Move / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+Overrides IssuanceCommands.aggregateState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/contract-hash.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/contract-hash.html new file mode 100644 index 0000000000..2d780f98e1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/contract-hash.html @@ -0,0 +1,18 @@ + + +Obligation.Commands.Move.contractHash - + + + +com.r3corda.contracts.asset / Obligation / Commands / Move / contractHash
+
+

contractHash

+ +val contractHash: SecureHash?
+Overrides MoveCommand.contractHash
+

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/index.html new file mode 100644 index 0000000000..be51f4f8f3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-move/index.html @@ -0,0 +1,51 @@ + + +Obligation.Commands.Move - + + + +com.r3corda.contracts.asset / Obligation / Commands / Move
+
+

Move

+data class Move<P> : Commands, IssuanceCommands<P>, MoveCommand
+

A command stating that a debt has been moved, optionally to fulfil another contract.

+

Parameters

+ +contractHash - the contract this move is for the attention of. Only that contracts verify function +should take the moved states into account when considering whether it is valid. Typically this will be +null.
+
+
+

Constructors

+ + + + + + + +
+<init> +Move(aggregateState: IssuanceDefinition<P>, contractHash: SecureHash? = null)

A command stating that a debt has been moved, optionally to fulfil another contract.

+
+

Properties

+ + + + + + + + + + + +
+aggregateState +val aggregateState: IssuanceDefinition<P>
+contractHash +val contractHash: SecureHash?

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/-init-.html new file mode 100644 index 0000000000..a5b6e45a4e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/-init-.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Net.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / Net / <init>
+
+

<init>

+Net(type: NetType)
+

Net two or more obligation states together in a close-out netting style. Limited to bilateral netting +as only the beneficiary (not the obligor) needs to sign.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/index.html new file mode 100644 index 0000000000..83b2cd921b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/index.html @@ -0,0 +1,40 @@ + + +Obligation.Commands.Net - + + + +com.r3corda.contracts.asset / Obligation / Commands / Net
+
+

Net

+data class Net : Commands
+

Net two or more obligation states together in a close-out netting style. Limited to bilateral netting +as only the beneficiary (not the obligor) needs to sign.

+
+
+

Constructors

+ + + + + + + +
+<init> +Net(type: NetType)

Net two or more obligation states together in a close-out netting style. Limited to bilateral netting +as only the beneficiary (not the obligor) needs to sign.

+
+

Properties

+ + + + + + + +
+type +val type: NetType
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/type.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/type.html new file mode 100644 index 0000000000..3af08472bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-net/type.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.Net.type - + + + +com.r3corda.contracts.asset / Obligation / Commands / Net / type
+
+

type

+ +val type: NetType
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/-init-.html new file mode 100644 index 0000000000..c64b831c47 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/-init-.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.SetLifecycle.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / SetLifecycle / <init>
+
+

<init>

+SetLifecycle(aggregateState: IssuanceDefinition<P>, lifecycle: Lifecycle)
+

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/aggregate-state.html new file mode 100644 index 0000000000..bff8bd5430 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/aggregate-state.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.SetLifecycle.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / Commands / SetLifecycle / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+Overrides IssuanceCommands.aggregateState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/index.html new file mode 100644 index 0000000000..606e87ee52 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/index.html @@ -0,0 +1,52 @@ + + +Obligation.Commands.SetLifecycle - + + + +com.r3corda.contracts.asset / Obligation / Commands / SetLifecycle
+
+

SetLifecycle

+data class SetLifecycle<P> : Commands, IssuanceCommands<P>
+

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+
+

Constructors

+ + + + + + + +
+<init> +SetLifecycle(aggregateState: IssuanceDefinition<P>, lifecycle: Lifecycle)

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+

Properties

+ + + + + + + + + + + + + + + +
+aggregateState +val aggregateState: IssuanceDefinition<P>
+inverse +val inverse: Lifecycle
+lifecycle +val lifecycle: Lifecycle
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/inverse.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/inverse.html new file mode 100644 index 0000000000..a80362154a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/inverse.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.SetLifecycle.inverse - + + + +com.r3corda.contracts.asset / Obligation / Commands / SetLifecycle / inverse
+
+

inverse

+ +val inverse: Lifecycle
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/lifecycle.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/lifecycle.html new file mode 100644 index 0000000000..15a756de27 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-set-lifecycle/lifecycle.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.SetLifecycle.lifecycle - + + + +com.r3corda.contracts.asset / Obligation / Commands / SetLifecycle / lifecycle
+
+

lifecycle

+ +val lifecycle: Lifecycle
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/-init-.html new file mode 100644 index 0000000000..05c39517e7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/-init-.html @@ -0,0 +1,19 @@ + + +Obligation.Commands.Settle.<init> - + + + +com.r3corda.contracts.asset / Obligation / Commands / Settle / <init>
+
+

<init>

+Settle(aggregateState: IssuanceDefinition<P>, amount: Amount<P>)
+

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+

See Also
+

MoveCommand

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/aggregate-state.html new file mode 100644 index 0000000000..edf1a102af --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/aggregate-state.html @@ -0,0 +1,16 @@ + + +Obligation.Commands.Settle.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / Commands / Settle / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+Overrides IssuanceCommands.aggregateState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/amount.html new file mode 100644 index 0000000000..95c0870d69 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/amount.html @@ -0,0 +1,15 @@ + + +Obligation.Commands.Settle.amount - + + + +com.r3corda.contracts.asset / Obligation / Commands / Settle / amount
+
+

amount

+ +val amount: Amount<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/index.html new file mode 100644 index 0000000000..b71abacd79 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/-settle/index.html @@ -0,0 +1,49 @@ + + +Obligation.Commands.Settle - + + + +com.r3corda.contracts.asset / Obligation / Commands / Settle
+
+

Settle

+data class Settle<P> : Commands, IssuanceCommands<P>
+

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+

See Also
+

MoveCommand

+

+
+
+

Constructors

+ + + + + + + +
+<init> +Settle(aggregateState: IssuanceDefinition<P>, amount: Amount<P>)

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+
+

Properties

+ + + + + + + + + + + +
+aggregateState +val aggregateState: IssuanceDefinition<P>
+amount +val amount: Amount<P>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/index.html new file mode 100644 index 0000000000..84f7523b8d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-commands/index.html @@ -0,0 +1,118 @@ + + +Obligation.Commands - + + + +com.r3corda.contracts.asset / Obligation / Commands
+
+

Commands

+interface Commands : CommandData
+
+
+

Types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Exit +data class Exit<P> : Commands, IssuanceCommands<P>

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+Issue +data class Issue<P> : Commands, IssuanceCommands<P>

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+Move +data class Move<P> : Commands, IssuanceCommands<P>, MoveCommand

A command stating that a debt has been moved, optionally to fulfil another contract.

+
+Net +data class Net : Commands

Net two or more obligation states together in a close-out netting style. Limited to bilateral netting +as only the beneficiary (not the obligor) needs to sign.

+
+SetLifecycle +data class SetLifecycle<P> : Commands, IssuanceCommands<P>

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+Settle +data class Settle<P> : Commands, IssuanceCommands<P>

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+
+

Inheritors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+Exit +data class Exit<P> : Commands, IssuanceCommands<P>

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+Issue +data class Issue<P> : Commands, IssuanceCommands<P>

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+Move +data class Move<P> : Commands, IssuanceCommands<P>, MoveCommand

A command stating that a debt has been moved, optionally to fulfil another contract.

+
+Net +data class Net : Commands

Net two or more obligation states together in a close-out netting style. Limited to bilateral netting +as only the beneficiary (not the obligor) needs to sign.

+
+SetLifecycle +data class SetLifecycle<P> : Commands, IssuanceCommands<P>

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+Settle +data class Settle<P> : Commands, IssuanceCommands<P>

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-init-.html new file mode 100644 index 0000000000..aa410b900f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-init-.html @@ -0,0 +1,21 @@ + + +Obligation.<init> - + + + +com.r3corda.contracts.asset / Obligation / <init>
+
+

<init>

+Obligation()
+

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/aggregate-state.html new file mode 100644 index 0000000000..9958e98a9c --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/aggregate-state.html @@ -0,0 +1,15 @@ + + +Obligation.IssuanceCommands.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / IssuanceCommands / aggregateState
+
+

aggregateState

+ +abstract val aggregateState: IssuanceDefinition<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/index.html new file mode 100644 index 0000000000..150871e311 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-commands/index.html @@ -0,0 +1,70 @@ + + +Obligation.IssuanceCommands - + + + +com.r3corda.contracts.asset / Obligation / IssuanceCommands
+
+

IssuanceCommands

+interface IssuanceCommands<P> : CommandData
+

Interface for commands that apply to states grouped by issuance definition

+
+
+

Properties

+ + + + + + + +
+aggregateState +abstract val aggregateState: IssuanceDefinition<P>
+

Inheritors

+ + + + + + + + + + + + + + + + + + + + + + + +
+Exit +data class Exit<P> : Commands, IssuanceCommands<P>

A command stating that the debt is being released by the beneficiary. Normally would indicate +either settlement outside of the ledger, or that the obligor is unable to pay.

+
+Issue +data class Issue<P> : Commands, IssuanceCommands<P>

Allows new obligation states to be issued into existence: the nonce ("number used once") ensures the +transaction has a unique ID even when there are no inputs.

+
+Move +data class Move<P> : Commands, IssuanceCommands<P>, MoveCommand

A command stating that a debt has been moved, optionally to fulfil another contract.

+
+SetLifecycle +data class SetLifecycle<P> : Commands, IssuanceCommands<P>

A command stating that the beneficiary is moving the contract into the defaulted state as it has not been settled +by the due date, or resetting a defaulted contract back to the issued state.

+
+Settle +data class Settle<P> : Commands, IssuanceCommands<P>

A command stating that the obligor is settling some or all of the amount owed by transferring a suitable +state object to the beneficiary. If this reduces the balance to zero, the state object is destroyed.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/-init-.html new file mode 100644 index 0000000000..9889000d66 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/-init-.html @@ -0,0 +1,20 @@ + + +Obligation.IssuanceDefinition.<init> - + + + +com.r3corda.contracts.asset / Obligation / IssuanceDefinition / <init>
+
+

<init>

+IssuanceDefinition(obligor: Party, template: StateTemplate<P>)
+

Subset of state, containing the elements specified when issuing a new settlement contract. +TODO: This needs to be something common to contracts that we can be obliged to pay, and moved +out into core accordingly.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/index.html new file mode 100644 index 0000000000..682ee1a59a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/index.html @@ -0,0 +1,62 @@ + + +Obligation.IssuanceDefinition - + + + +com.r3corda.contracts.asset / Obligation / IssuanceDefinition
+
+

IssuanceDefinition

+data class IssuanceDefinition<P>
+

Subset of state, containing the elements specified when issuing a new settlement contract. +TODO: This needs to be something common to contracts that we can be obliged to pay, and moved +out into core accordingly.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+

Constructors

+ + + + + + + +
+<init> +IssuanceDefinition(obligor: Party, template: StateTemplate<P>)

Subset of state, containing the elements specified when issuing a new settlement contract. +TODO: This needs to be something common to contracts that we can be obliged to pay, and moved +out into core accordingly.

+
+

Properties

+ + + + + + + + + + + +
+obligor +val obligor: Party
+template +val template: StateTemplate<P>
+

Extension Functions

+ + + + + + + +
+at +infix fun <T> IssuanceDefinition<T>.at(dueBefore: Instant): IssuanceDefinition<T>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/obligor.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/obligor.html new file mode 100644 index 0000000000..74c795c24d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/obligor.html @@ -0,0 +1,15 @@ + + +Obligation.IssuanceDefinition.obligor - + + + +com.r3corda.contracts.asset / Obligation / IssuanceDefinition / obligor
+
+

obligor

+ +val obligor: Party
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/template.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/template.html new file mode 100644 index 0000000000..57d9a58a4e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-issuance-definition/template.html @@ -0,0 +1,15 @@ + + +Obligation.IssuanceDefinition.template - + + + +com.r3corda.contracts.asset / Obligation / IssuanceDefinition / template
+
+

template

+ +val template: StateTemplate<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-d-e-f-a-u-l-t-e-d.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-d-e-f-a-u-l-t-e-d.html new file mode 100644 index 0000000000..7642b4c541 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-d-e-f-a-u-l-t-e-d.html @@ -0,0 +1,16 @@ + + +Obligation.Lifecycle.DEFAULTED - + + + +com.r3corda.contracts.asset / Obligation / Lifecycle / DEFAULTED
+
+

DEFAULTED

+DEFAULTED
+

Indicates the contract has not been settled by its due date. Once in the defaulted state, +it can only be reverted to NORMAL state by the beneficiary.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-n-o-r-m-a-l.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-n-o-r-m-a-l.html new file mode 100644 index 0000000000..37524a64f7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/-n-o-r-m-a-l.html @@ -0,0 +1,15 @@ + + +Obligation.Lifecycle.NORMAL - + + + +com.r3corda.contracts.asset / Obligation / Lifecycle / NORMAL
+
+

NORMAL

+NORMAL
+

Default lifecycle state for a contract, in which it can be settled normally

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/index.html new file mode 100644 index 0000000000..842c4d81c5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-lifecycle/index.html @@ -0,0 +1,37 @@ + + +Obligation.Lifecycle - + + + +com.r3corda.contracts.asset / Obligation / Lifecycle
+
+

Lifecycle

+enum class Lifecycle
+

Represents where in its lifecycle a contract state is, which in turn controls the commands that can be applied +to the state. Most states will not leave the NORMAL lifecycle. Note that settled (as an end lifecycle) is +represented by absence of the state on transaction output.

+
+
+

Enum Values

+ + + + + + + + + + + +
+NORMAL +

Default lifecycle state for a contract, in which it can be settled normally

+
+DEFAULTED +

Indicates the contract has not been settled by its due date. Once in the defaulted state, +it can only be reverted to NORMAL state by the beneficiary.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/-init-.html new file mode 100644 index 0000000000..76c45cb32d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/-init-.html @@ -0,0 +1,20 @@ + + +Obligation.MultilateralNetState.<init> - + + + +com.r3corda.contracts.asset / Obligation / MultilateralNetState / <init>
+
+

<init>

+MultilateralNetState(template: StateTemplate<P>)
+

Subset of state, containing the elements which must match for two or more obligation transactions to be candidates +for netting (this does not include the checks to enforce that everyones amounts received are the same at the end, +which is handled under the verify() function). +In comparison to BilateralNetState, this doesnt include the parties keys, as ensuring balances match on +input and output is handled elsewhere. +Used in cases where all parties (or their proxies) are signing, such as central clearing.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/index.html new file mode 100644 index 0000000000..1811d4ecaf --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/index.html @@ -0,0 +1,48 @@ + + +Obligation.MultilateralNetState - + + + +com.r3corda.contracts.asset / Obligation / MultilateralNetState
+
+

MultilateralNetState

+data class MultilateralNetState<P> : NetState<P>
+

Subset of state, containing the elements which must match for two or more obligation transactions to be candidates +for netting (this does not include the checks to enforce that everyones amounts received are the same at the end, +which is handled under the verify() function). +In comparison to BilateralNetState, this doesnt include the parties keys, as ensuring balances match on +input and output is handled elsewhere. +Used in cases where all parties (or their proxies) are signing, such as central clearing.

+
+
+

Constructors

+ + + + + + + +
+<init> +MultilateralNetState(template: StateTemplate<P>)

Subset of state, containing the elements which must match for two or more obligation transactions to be candidates +for netting (this does not include the checks to enforce that everyones amounts received are the same at the end, +which is handled under the verify() function). +In comparison to BilateralNetState, this doesnt include the parties keys, as ensuring balances match on +input and output is handled elsewhere. +Used in cases where all parties (or their proxies) are signing, such as central clearing.

+
+

Properties

+ + + + + + + +
+template +val template: StateTemplate<P>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/template.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/template.html new file mode 100644 index 0000000000..79d0eb9272 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-multilateral-net-state/template.html @@ -0,0 +1,16 @@ + + +Obligation.MultilateralNetState.template - + + + +com.r3corda.contracts.asset / Obligation / MultilateralNetState / template
+
+

template

+ +val template: StateTemplate<P>
+Overrides NetState.template
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/index.html new file mode 100644 index 0000000000..d182442adb --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/index.html @@ -0,0 +1,53 @@ + + +Obligation.NetState - + + + +com.r3corda.contracts.asset / Obligation / NetState
+
+

NetState

+interface NetState<P>
+

Common interface for the state subsets used when determining nettability of two or more states. Exposes the +underlying issued thing.

+
+
+

Properties

+ + + + + + + +
+template +abstract val template: StateTemplate<P>
+

Inheritors

+ + + + + + + + + + + +
+BilateralNetState +data class BilateralNetState<P> : NetState<P>

Subset of state, containing the elements which must match for two obligation transactions to be nettable. +If two obligation state objects produce equal bilateral net states, they are considered safe to net directly. +Bilateral states are used in close-out netting.

+
+MultilateralNetState +data class MultilateralNetState<P> : NetState<P>

Subset of state, containing the elements which must match for two or more obligation transactions to be candidates +for netting (this does not include the checks to enforce that everyones amounts received are the same at the end, +which is handled under the verify() function). +In comparison to BilateralNetState, this doesnt include the parties keys, as ensuring balances match on +input and output is handled elsewhere. +Used in cases where all parties (or their proxies) are signing, such as central clearing.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/template.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/template.html new file mode 100644 index 0000000000..fac3c14750 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-net-state/template.html @@ -0,0 +1,15 @@ + + +Obligation.NetState.template - + + + +com.r3corda.contracts.asset / Obligation / NetState / template
+
+

template

+ +abstract val template: StateTemplate<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/-init-.html new file mode 100644 index 0000000000..2e798540c3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/-init-.html @@ -0,0 +1,18 @@ + + +Obligation.StateTemplate.<init> - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / <init>
+
+

<init>

+StateTemplate(acceptableContracts: NonEmptySet<SecureHash>, acceptableIssuedProducts: NonEmptySet<Issued<P>>, dueBefore: Instant, timeTolerance: Duration = Duration.ofSeconds(30))
+

Subset of state, containing the elements specified when issuing a new settlement contract.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-contracts.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-contracts.html new file mode 100644 index 0000000000..3a668ea9cc --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-contracts.html @@ -0,0 +1,16 @@ + + +Obligation.StateTemplate.acceptableContracts - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / acceptableContracts
+
+

acceptableContracts

+ +val acceptableContracts: NonEmptySet<SecureHash>
+

The hash of the asset contract were willing to accept in payment for this debt.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-issued-products.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-issued-products.html new file mode 100644 index 0000000000..473b35da6d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/acceptable-issued-products.html @@ -0,0 +1,16 @@ + + +Obligation.StateTemplate.acceptableIssuedProducts - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / acceptableIssuedProducts
+
+

acceptableIssuedProducts

+ +val acceptableIssuedProducts: NonEmptySet<Issued<P>>
+

The parties whose assets we are willing to accept in payment for this debt.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/due-before.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/due-before.html new file mode 100644 index 0000000000..5da6aaab3e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/due-before.html @@ -0,0 +1,16 @@ + + +Obligation.StateTemplate.dueBefore - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / dueBefore
+
+

dueBefore

+ +val dueBefore: Instant
+

When the contract must be settled by.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/index.html new file mode 100644 index 0000000000..8e22c54fe9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/index.html @@ -0,0 +1,68 @@ + + +Obligation.StateTemplate - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate
+
+

StateTemplate

+data class StateTemplate<P>
+

Subset of state, containing the elements specified when issuing a new settlement contract.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+

Constructors

+ + + + + + + +
+<init> +StateTemplate(acceptableContracts: NonEmptySet<SecureHash>, acceptableIssuedProducts: NonEmptySet<Issued<P>>, dueBefore: Instant, timeTolerance: Duration = Duration.ofSeconds(30))

Subset of state, containing the elements specified when issuing a new settlement contract.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + +
+acceptableContracts +val acceptableContracts: NonEmptySet<SecureHash>

The hash of the asset contract were willing to accept in payment for this debt.

+
+acceptableIssuedProducts +val acceptableIssuedProducts: NonEmptySet<Issued<P>>

The parties whose assets we are willing to accept in payment for this debt.

+
+dueBefore +val dueBefore: Instant

When the contract must be settled by.

+
+product +val product: P
+timeTolerance +val timeTolerance: Duration
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/product.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/product.html new file mode 100644 index 0000000000..7681b329e0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/product.html @@ -0,0 +1,15 @@ + + +Obligation.StateTemplate.product - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / product
+
+

product

+ +val product: P
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/time-tolerance.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/time-tolerance.html new file mode 100644 index 0000000000..e2c5837d99 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state-template/time-tolerance.html @@ -0,0 +1,15 @@ + + +Obligation.StateTemplate.timeTolerance - + + + +com.r3corda.contracts.asset / Obligation / StateTemplate / timeTolerance
+
+

timeTolerance

+ +val timeTolerance: Duration
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/-init-.html new file mode 100644 index 0000000000..4e73b2558e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/-init-.html @@ -0,0 +1,20 @@ + + +Obligation.State.<init> - + + + +com.r3corda.contracts.asset / Obligation / State / <init>
+
+

<init>

+State(lifecycle: Lifecycle = Lifecycle.NORMAL, obligor: Party, template: StateTemplate<P>, quantity: Long, beneficiary: PublicKey)
+

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-contracts.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-contracts.html new file mode 100644 index 0000000000..d1d9b7fbb4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-contracts.html @@ -0,0 +1,15 @@ + + +Obligation.State.acceptableContracts - + + + +com.r3corda.contracts.asset / Obligation / State / acceptableContracts
+
+

acceptableContracts

+ +val acceptableContracts: NonEmptySet<SecureHash>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-issuance-definitions.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-issuance-definitions.html new file mode 100644 index 0000000000..356bf3a180 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/acceptable-issuance-definitions.html @@ -0,0 +1,15 @@ + + +Obligation.State.acceptableIssuanceDefinitions - + + + +com.r3corda.contracts.asset / Obligation / State / acceptableIssuanceDefinitions
+
+

acceptableIssuanceDefinitions

+ +val acceptableIssuanceDefinitions: NonEmptySet<*>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/aggregate-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/aggregate-state.html new file mode 100644 index 0000000000..42b3213ed7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/aggregate-state.html @@ -0,0 +1,15 @@ + + +Obligation.State.aggregateState - + + + +com.r3corda.contracts.asset / Obligation / State / aggregateState
+
+

aggregateState

+ +val aggregateState: IssuanceDefinition<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/amount.html new file mode 100644 index 0000000000..8d771e00c5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/amount.html @@ -0,0 +1,15 @@ + + +Obligation.State.amount - + + + +com.r3corda.contracts.asset / Obligation / State / amount
+
+

amount

+ +val amount: Amount<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/beneficiary.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/beneficiary.html new file mode 100644 index 0000000000..50a5913f2d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/beneficiary.html @@ -0,0 +1,16 @@ + + +Obligation.State.beneficiary - + + + +com.r3corda.contracts.asset / Obligation / State / beneficiary
+
+

beneficiary

+ +val beneficiary: PublicKey
+

The public key of the entity the contract pays to

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/bilateral-net-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/bilateral-net-state.html new file mode 100644 index 0000000000..8534329c23 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/bilateral-net-state.html @@ -0,0 +1,22 @@ + + +Obligation.State.bilateralNetState - + + + +com.r3corda.contracts.asset / Obligation / State / bilateralNetState
+
+

bilateralNetState

+ +val bilateralNetState: BilateralNetState<P>
+Overrides BilateralNettableState.bilateralNetState
+

Returns an object used to determine if two states can be subject to close-out netting. If two states return +equal objects, they can be close out netted together.

+

Getter
+

Returns an object used to determine if two states can be subject to close-out netting. If two states return +equal objects, they can be close out netted together.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/contract.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/contract.html new file mode 100644 index 0000000000..b52d711d52 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/contract.html @@ -0,0 +1,43 @@ + + +Obligation.State.contract - + + + +com.r3corda.contracts.asset / Obligation / State / contract
+
+

contract

+ +val contract: Obligation<Currency>
+Overrides ContractState.contract
+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/due-before.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/due-before.html new file mode 100644 index 0000000000..7cb421c771 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/due-before.html @@ -0,0 +1,15 @@ + + +Obligation.State.dueBefore - + + + +com.r3corda.contracts.asset / Obligation / State / dueBefore
+
+

dueBefore

+ +val dueBefore: Instant
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/index.html new file mode 100644 index 0000000000..d35f1d12eb --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/index.html @@ -0,0 +1,209 @@ + + +Obligation.State - + + + +com.r3corda.contracts.asset / Obligation / State
+
+

State

+data class State<P> : FungibleAssetState<P, IssuanceDefinition<P>>, BilateralNettableState<State<P>>
+

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+

Constructors

+ + + + + + + +
+<init> +State(lifecycle: Lifecycle = Lifecycle.NORMAL, obligor: Party, template: StateTemplate<P>, quantity: Long, beneficiary: PublicKey)

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+acceptableContracts +val acceptableContracts: NonEmptySet<SecureHash>
+acceptableIssuanceDefinitions +val acceptableIssuanceDefinitions: NonEmptySet<*>
+aggregateState +val aggregateState: IssuanceDefinition<P>
+amount +val amount: Amount<P>
+beneficiary +val beneficiary: PublicKey

The public key of the entity the contract pays to

+
+bilateralNetState +val bilateralNetState: BilateralNetState<P>

Returns an object used to determine if two states can be subject to close-out netting. If two states return +equal objects, they can be close out netted together.

+
+contract +val contract: Obligation<Currency>

An instance of the contract class that will verify this state.

+
+dueBefore +val dueBefore: Instant
+issuanceDef +val issuanceDef: IssuanceDefinition<P>
+lifecycle +var lifecycle: Lifecycle
+multilateralNetState +val multilateralNetState: MultilateralNetState<P>
+obligor +val obligor: Party

Where the debt originates from (obligor)

+
+owner +val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+
+participants +val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+productAmount +val productAmount: Amount<P>
+quantity +val quantity: Long
+template +val template: StateTemplate<P>
+

Functions

+ + + + + + + + + + + + + + + + + + + +
+move +fun move(newAmount: Amount<P>, newOwner: PublicKey): State<P>
+net +fun net(other: State<P>): State<P>

Perform bilateral netting of this state with another state. The two states must be compatible (as in +bilateralNetState objects are equal).

+
+toString +fun toString(): String
+withNewOwner +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+

Extension Functions

+ + + + + + + + + + + + + + + + + + + +
+at +infix fun <T> State<T>.at(dueBefore: Instant): State<T>
+between +infix fun <T> State<T>.between(parties: <ERROR CLASS><Party, PublicKey>): State<T>
+issued by +infix fun <T> State<T>.issued by(party: Party): State<T>
+owned by +infix fun <T> State<T>.owned by(owner: PublicKey): <ERROR CLASS>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/issuance-def.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/issuance-def.html new file mode 100644 index 0000000000..c7e58c54ae --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/issuance-def.html @@ -0,0 +1,16 @@ + + +Obligation.State.issuanceDef - + + + +com.r3corda.contracts.asset / Obligation / State / issuanceDef
+
+

issuanceDef

+ +val issuanceDef: IssuanceDefinition<P>
+Overrides FungibleAssetState.issuanceDef
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/lifecycle.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/lifecycle.html new file mode 100644 index 0000000000..e53e32620d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/lifecycle.html @@ -0,0 +1,15 @@ + + +Obligation.State.lifecycle - + + + +com.r3corda.contracts.asset / Obligation / State / lifecycle
+
+

lifecycle

+ +var lifecycle: Lifecycle
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/move.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/move.html new file mode 100644 index 0000000000..57c87b1e33 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/move.html @@ -0,0 +1,15 @@ + + +Obligation.State.move - + + + +com.r3corda.contracts.asset / Obligation / State / move
+
+

move

+ +fun move(newAmount: Amount<P>, newOwner: PublicKey): State<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/multilateral-net-state.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/multilateral-net-state.html new file mode 100644 index 0000000000..520edcd1ab --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/multilateral-net-state.html @@ -0,0 +1,15 @@ + + +Obligation.State.multilateralNetState - + + + +com.r3corda.contracts.asset / Obligation / State / multilateralNetState
+
+

multilateralNetState

+ +val multilateralNetState: MultilateralNetState<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/net.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/net.html new file mode 100644 index 0000000000..6bcc04c4fa --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/net.html @@ -0,0 +1,17 @@ + + +Obligation.State.net - + + + +com.r3corda.contracts.asset / Obligation / State / net
+
+

net

+ +fun net(other: State<P>): State<P>
+

Perform bilateral netting of this state with another state. The two states must be compatible (as in +bilateralNetState objects are equal).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/obligor.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/obligor.html new file mode 100644 index 0000000000..5145036d29 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/obligor.html @@ -0,0 +1,16 @@ + + +Obligation.State.obligor - + + + +com.r3corda.contracts.asset / Obligation / State / obligor
+
+

obligor

+ +val obligor: Party
+

Where the debt originates from (obligor)

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/owner.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/owner.html new file mode 100644 index 0000000000..85b1a8b720 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/owner.html @@ -0,0 +1,20 @@ + + +Obligation.State.owner - + + + +com.r3corda.contracts.asset / Obligation / State / owner
+
+

owner

+ +val owner: PublicKey
+Overrides OwnableState.owner
+

There must be a MoveCommand signed by this key to claim the amount

+

Getter
+

There must be a MoveCommand signed by this key to claim the amount

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/participants.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/participants.html new file mode 100644 index 0000000000..94bbb94bd5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/participants.html @@ -0,0 +1,34 @@ + + +Obligation.State.participants - + + + +com.r3corda.contracts.asset / Obligation / State / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/product-amount.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/product-amount.html new file mode 100644 index 0000000000..59d6383ed5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/product-amount.html @@ -0,0 +1,16 @@ + + +Obligation.State.productAmount - + + + +com.r3corda.contracts.asset / Obligation / State / productAmount
+
+

productAmount

+ +val productAmount: Amount<P>
+Overrides FungibleAssetState.productAmount
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/quantity.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/quantity.html new file mode 100644 index 0000000000..624ed322f8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/quantity.html @@ -0,0 +1,15 @@ + + +Obligation.State.quantity - + + + +com.r3corda.contracts.asset / Obligation / State / quantity
+
+

quantity

+ +val quantity: Long
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/template.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/template.html new file mode 100644 index 0000000000..8283121696 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/template.html @@ -0,0 +1,15 @@ + + +Obligation.State.template - + + + +com.r3corda.contracts.asset / Obligation / State / template
+
+

template

+ +val template: StateTemplate<P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/to-string.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/to-string.html new file mode 100644 index 0000000000..d3ae40b4bd --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/to-string.html @@ -0,0 +1,15 @@ + + +Obligation.State.toString - + + + +com.r3corda.contracts.asset / Obligation / State / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/with-new-owner.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/with-new-owner.html new file mode 100644 index 0000000000..36ca43cbb3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/with-new-owner.html @@ -0,0 +1,17 @@ + + +Obligation.State.withNewOwner - + + + +com.r3corda.contracts.asset / Obligation / State / withNewOwner
+
+

withNewOwner

+ +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
+Overrides OwnableState.withNewOwner
+

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-close-out-netting.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-close-out-netting.html new file mode 100644 index 0000000000..65c37cd33f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-close-out-netting.html @@ -0,0 +1,23 @@ + + +Obligation.generateCloseOutNetting - + + + +com.r3corda.contracts.asset / Obligation / generateCloseOutNetting
+
+

generateCloseOutNetting

+ +fun generateCloseOutNetting(tx: TransactionBuilder, signer: PublicKey, vararg states: State<P>): Unit
+

Generate a transaction performing close-out netting of two or more states.

+

Parameters

+ +signer - the party who will sign the transaction. Must be one of the obligor or beneficiary.
+
+ +states - two or more states, which must be compatible for bilateral netting (same issuance definitions, +and same parties involved).
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-issue.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-issue.html new file mode 100644 index 0000000000..38d8ecf3c7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-issue.html @@ -0,0 +1,16 @@ + + +Obligation.generateIssue - + + + +com.r3corda.contracts.asset / Obligation / generateIssue
+
+

generateIssue

+ +fun generateIssue(tx: TransactionBuilder, obligor: Party, issuanceDef: StateTemplate<P>, pennies: Long, beneficiary: PublicKey, notary: Party): Unit
+

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-payment-netting.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-payment-netting.html new file mode 100644 index 0000000000..c2321893d5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-payment-netting.html @@ -0,0 +1,15 @@ + + +Obligation.generatePaymentNetting - + + + +com.r3corda.contracts.asset / Obligation / generatePaymentNetting
+
+

generatePaymentNetting

+ +fun generatePaymentNetting(tx: TransactionBuilder, issued: Issued<P>, notary: Party, vararg states: State<P>): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-set-lifecycle.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-set-lifecycle.html new file mode 100644 index 0000000000..0efd6a6520 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-set-lifecycle.html @@ -0,0 +1,20 @@ + + +Obligation.generateSetLifecycle - + + + +com.r3corda.contracts.asset / Obligation / generateSetLifecycle
+
+

generateSetLifecycle

+ +fun generateSetLifecycle(tx: TransactionBuilder, statesAndRefs: List<StateAndRef<State<P>>>, lifecycle: Lifecycle, notary: Party): Unit
+

Generate a transaction changing the lifecycle of one or more state objects.

+

Parameters

+ +statesAndRefs - a list of state objects, which MUST all have the same issuance definition. This avoids +potential complications arising from different deadlines applying to different states.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-settle.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-settle.html new file mode 100644 index 0000000000..a6a480a4b5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-settle.html @@ -0,0 +1,27 @@ + + +Obligation.generateSettle - + + + +com.r3corda.contracts.asset / Obligation / generateSettle
+
+

generateSettle

+ +fun generateSettle(tx: TransactionBuilder, statesAndRefs: Iterable<StateAndRef<State<P>>>, assetStatesAndRefs: Iterable<StateAndRef<FungibleAssetState<P, *>>>, moveCommand: MoveCommand, notary: Party): Unit
+

Parameters

+ +statesAndRefs - a list of state objects, which MUST all have the same aggregate state. This is done as +only a single settlement command can be present in a transaction, to avoid potential problems with allocating +assets to different obligation issuances.
+
+ +assetStatesAndRefs - a list of fungible asset state objects, which MUST all be of the same issued product. +It is strongly encouraged that these all have the same beneficiary.
+
+ +moveCommand - the command used to move the asset state objects to their new owner.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/index.html new file mode 100644 index 0000000000..1b6555517e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/index.html @@ -0,0 +1,194 @@ + + +Obligation - + + + +com.r3corda.contracts.asset / Obligation
+
+

Obligation

+class Obligation<P> : Contract
+

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+

Parameters

+ +P - the product the obligation is for payment of.
+
+
+

Types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+BilateralNetState +data class BilateralNetState<P> : NetState<P>

Subset of state, containing the elements which must match for two obligation transactions to be nettable. +If two obligation state objects produce equal bilateral net states, they are considered safe to net directly. +Bilateral states are used in close-out netting.

+
+Commands +interface Commands : CommandData
+IssuanceCommands +interface IssuanceCommands<P> : CommandData

Interface for commands that apply to states grouped by issuance definition

+
+IssuanceDefinition +data class IssuanceDefinition<P>

Subset of state, containing the elements specified when issuing a new settlement contract. +TODO: This needs to be something common to contracts that we can be obliged to pay, and moved +out into core accordingly.

+
+Lifecycle +enum class Lifecycle

Represents where in its lifecycle a contract state is, which in turn controls the commands that can be applied +to the state. Most states will not leave the NORMAL lifecycle. Note that settled (as an end lifecycle) is +represented by absence of the state on transaction output.

+
+MultilateralNetState +data class MultilateralNetState<P> : NetState<P>

Subset of state, containing the elements which must match for two or more obligation transactions to be candidates +for netting (this does not include the checks to enforce that everyones amounts received are the same at the end, +which is handled under the verify() function). +In comparison to BilateralNetState, this doesnt include the parties keys, as ensuring balances match on +input and output is handled elsewhere. +Used in cases where all parties (or their proxies) are signing, such as central clearing.

+
+NetState +interface NetState<P>

Common interface for the state subsets used when determining nettability of two or more states. Exposes the +underlying issued thing.

+
+State +data class State<P> : FungibleAssetState<P, IssuanceDefinition<P>>, BilateralNettableState<State<P>>

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+
+StateTemplate +data class StateTemplate<P>

Subset of state, containing the elements specified when issuing a new settlement contract.

+
+

Constructors

+ + + + + + + +
+<init> +Obligation()

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+
+

Properties

+ + + + + + + +
+legalContractReference +val legalContractReference: SecureHash

TODO:

+
+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+generateCloseOutNetting +fun generateCloseOutNetting(tx: TransactionBuilder, signer: PublicKey, vararg states: State<P>): Unit

Generate a transaction performing close-out netting of two or more states.

+
+generateIssue +fun generateIssue(tx: TransactionBuilder, obligor: Party, issuanceDef: StateTemplate<P>, pennies: Long, beneficiary: PublicKey, notary: Party): Unit

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

+
+generatePaymentNetting +fun generatePaymentNetting(tx: TransactionBuilder, issued: Issued<P>, notary: Party, vararg states: State<P>): Unit
+generateSetLifecycle +fun generateSetLifecycle(tx: TransactionBuilder, statesAndRefs: List<StateAndRef<State<P>>>, lifecycle: Lifecycle, notary: Party): Unit

Generate a transaction changing the lifecycle of one or more state objects.

+
+generateSettle +fun generateSettle(tx: TransactionBuilder, statesAndRefs: Iterable<StateAndRef<State<P>>>, assetStatesAndRefs: Iterable<StateAndRef<FungibleAssetState<P, *>>>, moveCommand: MoveCommand, notary: Party): Unit
+verify +fun verify(tx: TransactionForContract): Unit

This is the function EVERYONE runs

+
+verifyIssueCommand +fun verifyIssueCommand(inputs: List<State<P>>, outputs: List<State<P>>, issueCommand: AuthenticatedObject<Issue<P>>, issued: Issued<P>, obligor: Party): Unit
+verifyNetCommand +fun verifyNetCommand(inputs: Iterable<State<P>>, outputs: Iterable<State<P>>, command: AuthenticatedObject<Net>, netState: NetState<P>): Unit

Verify a netting command. This handles both close-out and payment netting.

+
+verifySetLifecycleCommand +fun verifySetLifecycleCommand(inputs: List<State<P>>, outputs: List<State<P>>, tx: TransactionForContract, setLifecycleCommand: AuthenticatedObject<SetLifecycle<P>>): Unit

A default command mutates inputs and produces identical outputs, except that the lifecycle changes.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/legal-contract-reference.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/legal-contract-reference.html new file mode 100644 index 0000000000..d914315927 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/legal-contract-reference.html @@ -0,0 +1,25 @@ + + +Obligation.legalContractReference - + + + +com.r3corda.contracts.asset / Obligation / legalContractReference
+
+

legalContractReference

+ +val legalContractReference: SecureHash
+Overrides Contract.legalContractReference
+

TODO:

+
  1. hash should be of the contents, not the URI

    +
  2. allow the content to be specified at time of instance creation?

    +

Motivation: its the difference between a state object referencing a programRef, which references a +legalContractReference and a state object which directly references both. The latter allows the legal wording +to evolve without requiring code changes. But creates a risk that users create objects governed by a program +that is inconsistent with the legal contract

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-issue-command.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-issue-command.html new file mode 100644 index 0000000000..525e12f466 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-issue-command.html @@ -0,0 +1,15 @@ + + +Obligation.verifyIssueCommand - + + + +com.r3corda.contracts.asset / Obligation / verifyIssueCommand
+
+

verifyIssueCommand

+ +protected fun verifyIssueCommand(inputs: List<State<P>>, outputs: List<State<P>>, issueCommand: AuthenticatedObject<Issue<P>>, issued: Issued<P>, obligor: Party): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-net-command.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-net-command.html new file mode 100644 index 0000000000..a897afe124 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-net-command.html @@ -0,0 +1,16 @@ + + +Obligation.verifyNetCommand - + + + +com.r3corda.contracts.asset / Obligation / verifyNetCommand
+
+

verifyNetCommand

+ +protected fun verifyNetCommand(inputs: Iterable<State<P>>, outputs: Iterable<State<P>>, command: AuthenticatedObject<Net>, netState: NetState<P>): Unit
+

Verify a netting command. This handles both close-out and payment netting.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-set-lifecycle-command.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-set-lifecycle-command.html new file mode 100644 index 0000000000..c741091d42 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify-set-lifecycle-command.html @@ -0,0 +1,16 @@ + + +Obligation.verifySetLifecycleCommand - + + + +com.r3corda.contracts.asset / Obligation / verifySetLifecycleCommand
+
+

verifySetLifecycleCommand

+ +protected fun verifySetLifecycleCommand(inputs: List<State<P>>, outputs: List<State<P>>, tx: TransactionForContract, setLifecycleCommand: AuthenticatedObject<SetLifecycle<P>>): Unit
+

A default command mutates inputs and produces identical outputs, except that the lifecycle changes.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify.html new file mode 100644 index 0000000000..0216827f0a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/verify.html @@ -0,0 +1,17 @@ + + +Obligation.verify - + + + +com.r3corda.contracts.asset / Obligation / verify
+
+

verify

+ +fun verify(tx: TransactionForContract): Unit
+Overrides Contract.verify
+

This is the function EVERYONE runs

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/cash-balances.html b/docs/build/html/api/com.r3corda.contracts.asset/cash-balances.html new file mode 100644 index 0000000000..aaaba11c55 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/cash-balances.html @@ -0,0 +1,17 @@ + + +cashBalances - + + + +com.r3corda.contracts.asset / cashBalances
+
+

cashBalances

+ +val Wallet.cashBalances: Map<Currency, Amount<Currency>>
+

Returns a map of how much cash we have in each currency, ignoring details like issuer. Note: currencies for +which we have no cash evaluate to null (not present in map), not 0.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/extract-amounts-due.html b/docs/build/html/api/com.r3corda.contracts.asset/extract-amounts-due.html new file mode 100644 index 0000000000..c64277dc3b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/extract-amounts-due.html @@ -0,0 +1,18 @@ + + +extractAmountsDue - + + + +com.r3corda.contracts.asset / extractAmountsDue
+
+

extractAmountsDue

+ +fun <P> extractAmountsDue(product: P, states: Iterable<State<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>
+

Convert a list of settlement states into total from each obligor to a beneficiary.

+

Return
+a map of obligor/beneficiary pairs to the balance due.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/index.html b/docs/build/html/api/com.r3corda.contracts.asset/index.html new file mode 100644 index 0000000000..ef53ead635 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/index.html @@ -0,0 +1,129 @@ + + +com.r3corda.contracts.asset - + + + +com.r3corda.contracts.asset
+
+

Package com.r3corda.contracts.asset

+

Types

+ + + + + + + + + + + + + + + + + + + +
+Cash +class Cash : FungibleAsset<Currency>

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +input and output states. Imagine a Bitcoin transaction but in which all UTXOs had a colour +(a blend of issuer+depositRef) and you couldnt merge outputs of two colours together, but you COULD put them in +the same transaction.

+
+FungibleAsset +abstract class FungibleAsset<T> : Contract

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States +contain assets which are equivalent (such as cash of the same currency), so records of their existence can +be merged or split as needed where the issuer is the same. For instance, dollars issued by the Fed are fungible and +countable (in cents), barrels of West Texas crude are fungible and countable (oil from two small containers +can be poured into one large container), shares of the same class in a specific company are fungible and +countable, and so on.

+
+FungibleAssetState +interface FungibleAssetState<T, I> : OwnableState

Common elements of cash contract states.

+
+Obligation +class Obligation<P> : Contract

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+
+

Exceptions

+ + + + + + + +
+InsufficientBalanceException +class InsufficientBalanceException : Exception
+

Extensions for External Classes

+ + + + + + + +
+kotlin.collections.Iterable +
+

Properties

+ + + + + + + + + + + + + + + +
+CASH_PROGRAM_ID +val CASH_PROGRAM_ID: Cash
+OBLIGATION_PROGRAM_ID +val OBLIGATION_PROGRAM_ID: Obligation<Currency>
+cashBalances +val Wallet.cashBalances: Map<Currency, Amount<Currency>>

Returns a map of how much cash we have in each currency, ignoring details like issuer. Note: currencies for +which we have no cash evaluate to null (not present in map), not 0.

+
+

Functions

+ + + + + + + + + + + + + + + +
+extractAmountsDue +fun <P> extractAmountsDue(product: P, states: Iterable<State<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>

Convert a list of settlement states into total from each obligor to a beneficiary.

+
+netAmountsDue +fun <P> netAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>

Net off the amounts due between parties.

+
+sumAmountsDue +fun <P> sumAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<PublicKey, Long>

Calculate the total balance movement for each party in the transaction, based off a summary of balances between +each obligor and beneficiary.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/index.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/index.html new file mode 100644 index 0000000000..ee4354b4dc --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/index.html @@ -0,0 +1,98 @@ + + +com.r3corda.contracts.asset.kotlin.collections.Iterable - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable
+
+

Extensions for kotlin.collections.Iterable

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+sumCash +fun Iterable<ContractState>.sumCash(): <ERROR CLASS>

Sums the cash states in the list, throwing an exception if there are none, or if any of the cash +states cannot be added together (i.e. are different currencies).

+
+sumCashBy +fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>

Sums the cash states in the list belonging to a single owner, throwing an exception +if there are none, or if any of the cash states cannot be added together (i.e. are +different currencies).

+
+sumCashOrNull +fun Iterable<ContractState>.sumCashOrNull(): <ERROR CLASS>

Sums the cash states in the list, returning null if there are none.

+
+sumCashOrZero +fun Iterable<ContractState>.sumCashOrZero(currency: Issued<Currency>): <ERROR CLASS>

Sums the cash states in the list, returning zero of the given currency if there are none.

+
+sumFungible +fun <T> Iterable<ContractState>.sumFungible(): <ERROR CLASS>

Sums the asset states in the list, throwing an exception if there are none, or if any of the asset +states cannot be added together (i.e. are different tokens).

+
+sumFungibleBy +fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>

Sums the asset states in the list belonging to a single owner, throwing an exception +if there are none, or if any of the asset states cannot be added together (i.e. are +different tokens).

+
+sumFungibleOrNull +fun <T> Iterable<ContractState>.sumFungibleOrNull(): <ERROR CLASS>

Sums the asset states in the list, returning null if there are none.

+
+sumFungibleOrZero +fun <T> Iterable<ContractState>.sumFungibleOrZero(token: Issued<T>): <ERROR CLASS>

Sums the asset states in the list, returning zero of the given token if there are none.

+
+sumObligations +fun <P> Iterable<ContractState>.sumObligations(): Amount<P>

Sums the obligation states in the list, throwing an exception if there are none. All state objects in the list are presumed to be nettable.

+
+sumObligationsOrNull +fun <P> Iterable<ContractState>.sumObligationsOrNull(): Amount<P>?

Sums the obligation states in the list, returning null if there are none.

+
+sumObligationsOrZero +fun <P> Iterable<ContractState>.sumObligationsOrZero(product: P): Amount<P>

Sums the obligation states in the list, returning zero of the given product if there are none.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-by.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-by.html new file mode 100644 index 0000000000..94c663004e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-by.html @@ -0,0 +1,18 @@ + + +sumCashBy - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashBy
+
+

sumCashBy

+ +fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>
+

Sums the cash states in the list belonging to a single owner, throwing an exception +if there are none, or if any of the cash states cannot be added together (i.e. are +different currencies).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-null.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-null.html new file mode 100644 index 0000000000..3503e531b1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-null.html @@ -0,0 +1,16 @@ + + +sumCashOrNull - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashOrNull
+
+

sumCashOrNull

+ +fun Iterable<ContractState>.sumCashOrNull(): <ERROR CLASS>
+

Sums the cash states in the list, returning null if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-zero.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-zero.html new file mode 100644 index 0000000000..fa691bb37b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash-or-zero.html @@ -0,0 +1,16 @@ + + +sumCashOrZero - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashOrZero
+
+

sumCashOrZero

+ +fun Iterable<ContractState>.sumCashOrZero(currency: Issued<Currency>): <ERROR CLASS>
+

Sums the cash states in the list, returning zero of the given currency if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash.html new file mode 100644 index 0000000000..6283fb4e19 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-cash.html @@ -0,0 +1,17 @@ + + +sumCash - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCash
+
+

sumCash

+ +fun Iterable<ContractState>.sumCash(): <ERROR CLASS>
+

Sums the cash states in the list, throwing an exception if there are none, or if any of the cash +states cannot be added together (i.e. are different currencies).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-by.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-by.html new file mode 100644 index 0000000000..cc0a42b341 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-by.html @@ -0,0 +1,18 @@ + + +sumFungibleBy - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleBy
+
+

sumFungibleBy

+ +fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>
+

Sums the asset states in the list belonging to a single owner, throwing an exception +if there are none, or if any of the asset states cannot be added together (i.e. are +different tokens).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-null.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-null.html new file mode 100644 index 0000000000..e2b4162f63 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-null.html @@ -0,0 +1,16 @@ + + +sumFungibleOrNull - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleOrNull
+
+

sumFungibleOrNull

+ +fun <T> Iterable<ContractState>.sumFungibleOrNull(): <ERROR CLASS>
+

Sums the asset states in the list, returning null if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-zero.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-zero.html new file mode 100644 index 0000000000..f4f1dc7628 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible-or-zero.html @@ -0,0 +1,16 @@ + + +sumFungibleOrZero - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleOrZero
+
+

sumFungibleOrZero

+ +fun <T> Iterable<ContractState>.sumFungibleOrZero(token: Issued<T>): <ERROR CLASS>
+

Sums the asset states in the list, returning zero of the given token if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible.html new file mode 100644 index 0000000000..b594939bb4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-fungible.html @@ -0,0 +1,17 @@ + + +sumFungible - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungible
+
+

sumFungible

+ +fun <T> Iterable<ContractState>.sumFungible(): <ERROR CLASS>
+

Sums the asset states in the list, throwing an exception if there are none, or if any of the asset +states cannot be added together (i.e. are different tokens).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-null.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-null.html new file mode 100644 index 0000000000..730805ad4a --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-null.html @@ -0,0 +1,16 @@ + + +sumObligationsOrNull - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumObligationsOrNull
+
+

sumObligationsOrNull

+ +fun <P> Iterable<ContractState>.sumObligationsOrNull(): Amount<P>?
+

Sums the obligation states in the list, returning null if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-zero.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-zero.html new file mode 100644 index 0000000000..79ff2da1f7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations-or-zero.html @@ -0,0 +1,16 @@ + + +sumObligationsOrZero - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumObligationsOrZero
+
+

sumObligationsOrZero

+ +fun <P> Iterable<ContractState>.sumObligationsOrZero(product: P): Amount<P>
+

Sums the obligation states in the list, returning zero of the given product if there are none.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations.html b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations.html new file mode 100644 index 0000000000..6d70942246 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/kotlin.collections.-iterable/sum-obligations.html @@ -0,0 +1,16 @@ + + +sumObligations - + + + +com.r3corda.contracts.asset / kotlin.collections.Iterable / sumObligations
+
+

sumObligations

+ +fun <P> Iterable<ContractState>.sumObligations(): Amount<P>
+

Sums the obligation states in the list, throwing an exception if there are none. All state objects in the list are presumed to be nettable.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/net-amounts-due.html b/docs/build/html/api/com.r3corda.contracts.asset/net-amounts-due.html new file mode 100644 index 0000000000..f95281b45d --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/net-amounts-due.html @@ -0,0 +1,16 @@ + + +netAmountsDue - + + + +com.r3corda.contracts.asset / netAmountsDue
+
+

netAmountsDue

+ +fun <P> netAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>
+

Net off the amounts due between parties.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/sum-amounts-due.html b/docs/build/html/api/com.r3corda.contracts.asset/sum-amounts-due.html new file mode 100644 index 0000000000..9b65b87b47 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/sum-amounts-due.html @@ -0,0 +1,21 @@ + + +sumAmountsDue - + + + +com.r3corda.contracts.asset / sumAmountsDue
+
+

sumAmountsDue

+ +fun <P> sumAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<PublicKey, Long>
+

Calculate the total balance movement for each party in the transaction, based off a summary of balances between +each obligor and beneficiary.

+

Parameters

+ +balances - payments due, indexed by obligor and beneficiary. Zero balances are stripped from the map before being +returned.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/deposit.html b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/deposit.html index a301089776..35629ba7c5 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/deposit.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/deposit.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / AssetIssuanceDefinition / deposit
+com.r3corda.contracts.asset / AssetIssuanceDefinition / deposit

deposit

- + abstract val deposit: PartyAndReference

Where the underlying asset backing this ledger entry can be found (propagated)


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/index.html index 8c90481cca..b140e10db6 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / AssetIssuanceDefinition
+com.r3corda.contracts.asset / AssetIssuanceDefinition

AssetIssuanceDefinition

interface AssetIssuanceDefinition<T> : IssuanceDefinition
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/token.html b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/token.html index 1f0863afa4..ff26264a37 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/token.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-asset-issuance-definition/token.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / AssetIssuanceDefinition / token
+com.r3corda.contracts.asset / AssetIssuanceDefinition / token

token

- + abstract val token: T


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html b/docs/build/html/api/com.r3corda.contracts.cash/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html index 45544c9893..663d79fe8f 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-c-a-s-h_-p-r-o-g-r-a-m_-i-d.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / CASH_PROGRAM_ID
+com.r3corda.contracts.asset / CASH_PROGRAM_ID

CASH_PROGRAM_ID

- + val CASH_PROGRAM_ID: Cash


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/-init-.html index 3101bfed2a..f56b66c5b4 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/-init-.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / Commands / Exit / <init>
+com.r3corda.contracts.asset / Cash / Commands / Exit / <init>

<init>

-Exit(amount: Amount<Currency>)
+Exit(amount: Amount<Currency>)

A command stating that money has been withdrawn from the shared ledger and is now accounted for in some other way.


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/amount.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/amount.html index 5178e04d6e..310f5ee798 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/amount.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/amount.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / Commands / Exit / amount
+com.r3corda.contracts.asset / Cash / Commands / Exit / amount

amount

- + val amount: Amount<Currency>
Overrides Exit.amount

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/index.html index 4d7475222e..b84e6c7ee1 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-exit/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / Cash / Commands / Exit
+com.r3corda.contracts.asset / Cash / Commands / Exit

Exit

data class Exit : Commands, Exit<Currency>
@@ -19,7 +19,7 @@ in some other way.

<init> -Exit(amount: Amount<Currency>)

A command stating that money has been withdrawn from the shared ledger and is now accounted for +Exit(amount: Amount<Currency>)

A command stating that money has been withdrawn from the shared ledger and is now accounted for in some other way.

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/-init-.html index d14e6d85de..ab8a7b3a61 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/-init-.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / Commands / Issue / <init>
+com.r3corda.contracts.asset / Cash / Commands / Issue / <init>

<init>

-Issue(nonce: Long = SecureRandom.getInstanceStrong().nextLong())
+Issue(nonce: Long = SecureRandom.getInstanceStrong().nextLong())

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction has a unique ID even when there are no inputs.


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/index.html index 5fb028818d..b24c274985 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / Cash / Commands / Issue
+com.r3corda.contracts.asset / Cash / Commands / Issue

Issue

data class Issue : Issue
@@ -19,7 +19,7 @@ has a unique ID even when there are no inputs.

<init> -Issue(nonce: Long = SecureRandom.getInstanceStrong().nextLong())

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction +Issue(nonce: Long = SecureRandom.getInstanceStrong().nextLong())

Allows new cash states to be issued into existence: the nonce ("number used once") ensures the transaction has a unique ID even when there are no inputs.

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/nonce.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/nonce.html index e9551f169b..cbac655421 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/nonce.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-commands/-issue/nonce.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / Commands / Issue / nonce
+com.r3corda.contracts.asset / Cash / Commands / Issue / nonce

nonce

- + val nonce: Long
Overrides Issue.nonce

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/-init-.html index 90b93a9810..78d3da604a 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/-init-.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / IssuanceDefinition / <init>
+com.r3corda.contracts.asset / Cash / IssuanceDefinition / <init>

<init>

-IssuanceDefinition(deposit: PartyAndReference, token: T)
+IssuanceDefinition(deposit: PartyAndReference, token: T)


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/deposit.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/deposit.html index a7af136488..1577a0c22a 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/deposit.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/deposit.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / IssuanceDefinition / deposit
+com.r3corda.contracts.asset / Cash / IssuanceDefinition / deposit

deposit

- + val deposit: PartyAndReference
Overrides AssetIssuanceDefinition.deposit

Where the underlying currency backing this ledger entry can be found (propagated)

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/index.html index 92ba11b85f..f3b3bd692b 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / Cash / IssuanceDefinition
+com.r3corda.contracts.asset / Cash / IssuanceDefinition

IssuanceDefinition

data class IssuanceDefinition<T> : AssetIssuanceDefinition<T>
@@ -17,7 +17,7 @@ <init> -IssuanceDefinition(deposit: PartyAndReference, token: T) +IssuanceDefinition(deposit: PartyAndReference, token: T) diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/token.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/token.html index f2198b84d9..446f4cce08 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/token.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-issuance-definition/token.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / IssuanceDefinition / token
+com.r3corda.contracts.asset / Cash / IssuanceDefinition / token

token

- + val token: T
Overrides AssetIssuanceDefinition.token

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/-init-.html index 051dafea4c..fd387fc606 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/-init-.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / <init>
+com.r3corda.contracts.asset / Cash / State / <init>

<init>

-State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey, notary: Party)
+State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey, notary: Party)

A state representing a cash claim against some party



diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/amount.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/amount.html index 875ded550f..459c6819d5 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/amount.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/amount.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / amount
+com.r3corda.contracts.asset / Cash / State / amount

amount

- + val amount: Amount<Currency>
Overrides State.amount

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/contract.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/contract.html index 2d4374c009..fed4080ebc 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/contract.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/contract.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / contract
+com.r3corda.contracts.asset / Cash / State / contract

contract

- + val contract: Cash
Overrides ContractState.contract

Contract by which the state belongs

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/deposit.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/deposit.html index 098ecb1ab7..8196717f65 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/deposit.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/deposit.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / deposit
+com.r3corda.contracts.asset / Cash / State / deposit

deposit

- + val deposit: PartyAndReference
Overrides State.deposit

Where the underlying currency backing this ledger entry can be found (propagated)

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/index.html index ce72e23d98..16d3ce9533 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / Cash / State
+com.r3corda.contracts.asset / Cash / State

State

data class State : State<Currency>
@@ -18,7 +18,7 @@ <init> -State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey, notary: Party)

A state representing a cash claim against some party

+State(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey, notary: Party)

A state representing a cash claim against some party

@@ -81,7 +81,7 @@ withNewOwner -fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

@@ -93,13 +93,13 @@ issued by -infix fun State.issued by(party: Party): State +infix fun State.issued by(party: Party): State owned by -infix fun State.owned by(owner: PublicKey): State +infix fun State.owned by(owner: PublicKey): State diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/issuance-def.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/issuance-def.html index e11f23a197..00f59635c9 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/issuance-def.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/issuance-def.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / issuanceDef
+com.r3corda.contracts.asset / Cash / State / issuanceDef

issuanceDef

- + val issuanceDef: IssuanceDefinition<Currency>
Overrides FungibleAssetState.issuanceDef

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/notary.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/notary.html index 9dbf7ee9ea..607a64a7d3 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/notary.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/notary.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / notary
+com.r3corda.contracts.asset / Cash / State / notary

notary

- + val notary: Party
Overrides State.notary

Identity of the notary that ensures this state is not used as an input to a transaction more than once

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/owner.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/owner.html index 156afc21eb..60b915aa35 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/owner.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/owner.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / owner
+com.r3corda.contracts.asset / Cash / State / owner

owner

- + val owner: PublicKey
Overrides State.owner

There must be a MoveCommand signed by this key to claim the amount

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/to-string.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/to-string.html index 1362fb6a6f..94c2abeecd 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/to-string.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/to-string.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / State / toString
+com.r3corda.contracts.asset / Cash / State / toString

toString

- + fun toString(): String


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/with-new-owner.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/with-new-owner.html index acb1a8c71c..d0fdf7138e 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/with-new-owner.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/-state/with-new-owner.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / Cash / State / withNewOwner
+com.r3corda.contracts.asset / Cash / State / withNewOwner

withNewOwner

- -fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
+ +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
Overrides OwnableState.withNewOwner

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-issue.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-issue.html index bbef2a8e04..df54fe9cb5 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-issue.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-issue.html @@ -4,16 +4,16 @@ -com.r3corda.contracts.cash / Cash / generateIssue
+com.r3corda.contracts.asset / Cash / generateIssue

generateIssue

- -fun generateIssue(tx: TransactionBuilder, issuanceDef: AssetIssuanceDefinition<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit
+ +fun generateIssue(tx: TransactionBuilder, issuanceDef: AssetIssuanceDefinition<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.



- -fun generateIssue(tx: TransactionBuilder, amount: Amount<Currency>, at: PartyAndReference, owner: PublicKey, notary: Party): Unit
+ +fun generateIssue(tx: TransactionBuilder, amount: Amount<Currency>, at: PartyAndReference, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.



diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-spend.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-spend.html index 096c6f0bca..ca1d11d271 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-spend.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/generate-spend.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / Cash / generateSpend
+com.r3corda.contracts.asset / Cash / generateSpend

generateSpend

- -fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>
+ +fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. Note that the wallet list is not updated: its up to you to do that.

Parameters

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/index.html index 5080176564..fe92eabb22 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / Cash
+com.r3corda.contracts.asset / Cash

Cash

class Cash : FungibleAsset<Currency>
@@ -79,15 +79,15 @@ the same transaction.

generateIssue -fun generateIssue(tx: TransactionBuilder, issuanceDef: AssetIssuanceDefinition<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.

-fun generateIssue(tx: TransactionBuilder, amount: Amount<Currency>, at: PartyAndReference, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

+fun generateIssue(tx: TransactionBuilder, issuanceDef: AssetIssuanceDefinition<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction from the given template, that starts out being owned by the given pubkey.

+fun generateIssue(tx: TransactionBuilder, amount: Amount<Currency>, at: PartyAndReference, owner: PublicKey, notary: Party): Unit

Puts together an issuance transaction for the specified amount that starts out being owned by the given pubkey.

generateSpend -fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. +fun generateSpend(tx: TransactionBuilder, amount: Amount<Currency>, to: PublicKey, cashStates: List<StateAndRef<State>>, onlyFromParties: Set<Party>? = null): List<PublicKey>

Generate a transaction that consumes one or more of the given input states to move money to the given pubkey. Note that the wallet list is not updated: its up to you to do that.

@@ -100,7 +100,7 @@ Note that the wallet list is not updated: its up to you to do that.

verify -open fun verify(tx: TransactionForVerification): Unit

This is the function EVERYONE runs

+open fun verify(tx: TransactionForVerification): Unit

This is the function EVERYONE runs

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-cash/legal-contract-reference.html b/docs/build/html/api/com.r3corda.contracts.cash/-cash/legal-contract-reference.html index d6776b7a41..5978af553b 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-cash/legal-contract-reference.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-cash/legal-contract-reference.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / Cash / legalContractReference
+com.r3corda.contracts.asset / Cash / legalContractReference

legalContractReference

- + val legalContractReference: SecureHash
Overrides Contract.legalContractReference

TODO:

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/amount.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/amount.html index 076438a8cc..40f49864c0 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/amount.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/amount.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAssetState / amount
+com.r3corda.contracts.asset / FungibleAssetState / amount

amount

- + abstract val amount: Amount<T>


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/deposit.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/deposit.html index 299676e75a..3589c82b02 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/deposit.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/deposit.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAssetState / deposit
+com.r3corda.contracts.asset / FungibleAssetState / deposit

deposit

- + abstract val deposit: PartyAndReference

Where the underlying currency backing this ledger entry can be found (propagated)


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/issuance-def.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/issuance-def.html index 8fcf9f7a8b..40ec6c2a50 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/issuance-def.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset-state/issuance-def.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAssetState / issuanceDef
+com.r3corda.contracts.asset / FungibleAssetState / issuanceDef

issuanceDef

- + abstract val issuanceDef: I


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/amount.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/amount.html index 481952eaba..cd30f12509 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/amount.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/amount.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / Commands / Exit / amount
+com.r3corda.contracts.asset / FungibleAsset / Commands / Exit / amount

amount

- + abstract val amount: Amount<T>


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/index.html index cbf15d9eba..5c7cde8417 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-exit/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset / Commands / Exit
+com.r3corda.contracts.asset / FungibleAsset / Commands / Exit

Exit

interface Exit<T> : Commands
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/index.html index a044b1f185..90e24de693 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset / Commands / Issue
+com.r3corda.contracts.asset / FungibleAsset / Commands / Issue

Issue

interface Issue : Commands
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/nonce.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/nonce.html index e3cdabc6f6..7e9375b9ff 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/nonce.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-issue/nonce.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / Commands / Issue / nonce
+com.r3corda.contracts.asset / FungibleAsset / Commands / Issue / nonce

nonce

- + abstract val nonce: Long


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-move.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-move.html index 89fda720ff..68c60d51ae 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-move.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-commands/-move.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset / Commands / Move
+com.r3corda.contracts.asset / FungibleAsset / Commands / Move

Move

interface Move : Commands
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-init-.html index bf8d4a2cca..0058e07544 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-init-.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset / <init>
+com.r3corda.contracts.asset / FungibleAsset / <init>

<init>

FungibleAsset()
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/amount.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/amount.html index 9b942f2354..cc262f412c 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/amount.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/amount.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / State / amount
+com.r3corda.contracts.asset / FungibleAsset / State / amount

amount

- + abstract val amount: Amount<T>
Overrides FungibleAssetState.amount

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/deposit.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/deposit.html index 7e8119cf05..5ee95110f0 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/deposit.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/deposit.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / State / deposit
+com.r3corda.contracts.asset / FungibleAsset / State / deposit

deposit

- + abstract val deposit: PartyAndReference
Overrides FungibleAssetState.deposit

Where the underlying asset backing this ledger entry can be found (propagated)

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/index.html index 155a9b194c..adf7971ac1 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset / State
+com.r3corda.contracts.asset / FungibleAsset / State

State

interface State<T> : FungibleAssetState<T, AssetIssuanceDefinition<T>>
diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/notary.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/notary.html index b4feb6c780..30ddb54fce 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/notary.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/notary.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / State / notary
+com.r3corda.contracts.asset / FungibleAsset / State / notary

notary

- + abstract val notary: Party
Overrides ContractState.notary

Identity of the notary that ensures this state is not used as an input to a transaction more than once

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/owner.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/owner.html index 015df89228..65b4b0cd45 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/owner.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/-state/owner.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / FungibleAsset / State / owner
+com.r3corda.contracts.asset / FungibleAsset / State / owner

owner

- + abstract val owner: PublicKey
Overrides OwnableState.owner

There must be a MoveCommand signed by this key to claim the amount

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/index.html index ec0662e349..572e123294 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / FungibleAsset
+com.r3corda.contracts.asset / FungibleAsset

FungibleAsset

abstract class FungibleAsset<T> : Contract
@@ -78,7 +78,7 @@ the contracts contents).

verify -open fun verify(tx: TransactionForVerification): Unit

This is the function EVERYONE runs

+open fun verify(tx: TransactionForVerification): Unit

This is the function EVERYONE runs

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/verify.html b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/verify.html index 8d9a996009..3114c7dda2 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-fungible-asset/verify.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / FungibleAsset / verify
+com.r3corda.contracts.asset / FungibleAsset / verify

verify

- -open fun verify(tx: TransactionForVerification): Unit
+ +open fun verify(tx: TransactionForVerification): Unit
Overrides Contract.verify

This is the function EVERYONE runs


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/-init-.html b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/-init-.html index bc075fdf5e..db5fc3d6c7 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/-init-.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / InsufficientBalanceException / <init>
+com.r3corda.contracts.asset / InsufficientBalanceException / <init>

<init>

-InsufficientBalanceException(amountMissing: Amount<*>)
+InsufficientBalanceException(amountMissing: Amount<*>)


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/amount-missing.html b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/amount-missing.html index d24c6f7020..9323ad1b72 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/amount-missing.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/amount-missing.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / InsufficientBalanceException / amountMissing
+com.r3corda.contracts.asset / InsufficientBalanceException / amountMissing

amountMissing

- + val amountMissing: Amount<*>


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/index.html b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/index.html index d306f5cc82..6616fccdfd 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/-insufficient-balance-exception/index.html @@ -4,7 +4,7 @@ -com.r3corda.contracts.cash / InsufficientBalanceException
+com.r3corda.contracts.asset / InsufficientBalanceException

InsufficientBalanceException

class InsufficientBalanceException : Exception
@@ -17,7 +17,7 @@ <init> -InsufficientBalanceException(amountMissing: Amount<*>) +InsufficientBalanceException(amountMissing: Amount<*>) diff --git a/docs/build/html/api/com.r3corda.contracts.cash/index.html b/docs/build/html/api/com.r3corda.contracts.cash/index.html index 80832fa684..333f510d81 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/index.html @@ -1,12 +1,12 @@ -com.r3corda.contracts.cash - +com.r3corda.contracts.asset - -com.r3corda.contracts.cash
+com.r3corda.contracts.asset

-

Package com.r3corda.contracts.cash

+

Package com.r3corda.contracts.asset

Types

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/index.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/index.html index 5b8ca017e8..04ee7fee4f 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/index.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/index.html @@ -1,10 +1,10 @@ -com.r3corda.contracts.cash.kotlin.collections.Iterable - +com.r3corda.contracts.asset.kotlin.collections.Iterable - -com.r3corda.contracts.cash / kotlin.collections.Iterable
+com.r3corda.contracts.asset / kotlin.collections.Iterable

Extensions for kotlin.collections.Iterable

@@ -21,7 +21,7 @@ states cannot be added together (i.e. are different currencies).

@@ -37,7 +37,7 @@ different currencies).

@@ -52,7 +52,7 @@ states cannot be added together (i.e. are different tokens).

@@ -68,7 +68,7 @@ different tokens).

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-by.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-by.html index 9065fe85d9..94c663004e 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-by.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-by.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumCashBy
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashBy

sumCashBy

- -fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>
+ +fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>

Sums the cash states in the list belonging to a single owner, throwing an exception if there are none, or if any of the cash states cannot be added together (i.e. are different currencies).

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-null.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-null.html index 2de2afb815..3503e531b1 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-null.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-null.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumCashOrNull
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashOrNull

sumCashOrNull

- +fun Iterable<ContractState>.sumCashOrNull(): <ERROR CLASS>

Sums the cash states in the list, returning null if there are none.


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-zero.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-zero.html index 306eae07c6..4b2a779908 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-zero.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash-or-zero.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumCashOrZero
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCashOrZero

sumCashOrZero

- -fun Iterable<ContractState>.sumCashOrZero(currency: Currency): <ERROR CLASS>
+ +fun Iterable<ContractState>.sumCashOrZero(currency: Currency): <ERROR CLASS>

Sums the cash states in the list, returning zero of the given currency if there are none.



diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash.html index 91578aa2fb..6283fb4e19 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-cash.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumCash
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumCash

sumCash

- +fun Iterable<ContractState>.sumCash(): <ERROR CLASS>

Sums the cash states in the list, throwing an exception if there are none, or if any of the cash states cannot be added together (i.e. are different currencies).

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-by.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-by.html index b1d90b04d2..cc0a42b341 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-by.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-by.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumFungibleBy
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleBy

sumFungibleBy

- -fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>
+ +fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>

Sums the asset states in the list belonging to a single owner, throwing an exception if there are none, or if any of the asset states cannot be added together (i.e. are different tokens).

diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-null.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-null.html index 31652ff2b0..e2b4162f63 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-null.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-null.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumFungibleOrNull
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleOrNull

sumFungibleOrNull

- +fun <T> Iterable<ContractState>.sumFungibleOrNull(): <ERROR CLASS>

Sums the asset states in the list, returning null if there are none.


diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-zero.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-zero.html index 2a2d710875..8b73f5d2b7 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-zero.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible-or-zero.html @@ -4,11 +4,11 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumFungibleOrZero
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungibleOrZero

sumFungibleOrZero

- -fun <T> Iterable<ContractState>.sumFungibleOrZero(token: T): <ERROR CLASS>
+ +fun <T> Iterable<ContractState>.sumFungibleOrZero(token: T): <ERROR CLASS>

Sums the asset states in the list, returning zero of the given token if there are none.



diff --git a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible.html b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible.html index 52e6305fd7..b594939bb4 100644 --- a/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible.html +++ b/docs/build/html/api/com.r3corda.contracts.cash/kotlin.collections.-iterable/sum-fungible.html @@ -4,10 +4,10 @@ -com.r3corda.contracts.cash / kotlin.collections.Iterable / sumFungible
+com.r3corda.contracts.asset / kotlin.collections.Iterable / sumFungible

sumFungible

- +fun <T> Iterable<ContractState>.sumFungible(): <ERROR CLASS>

Sums the asset states in the list, throwing an exception if there are none, or if any of the asset states cannot be added together (i.e. are different tokens).

diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-c-a-s-h.html b/docs/build/html/api/com.r3corda.contracts.testing/-c-a-s-h.html index 05953f3971..5c1d781fe3 100644 --- a/docs/build/html/api/com.r3corda.contracts.testing/-c-a-s-h.html +++ b/docs/build/html/api/com.r3corda.contracts.testing/-c-a-s-h.html @@ -8,7 +8,8 @@

CASH

-val Amount<Currency>.CASH: State
+val Amount<Currency>.CASH: State
+

Allows you to write 100.DOLLARS.CASH



diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r.html b/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r.html new file mode 100644 index 0000000000..09f333ef0e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r.html @@ -0,0 +1,15 @@ + + +DUMMY_CASH_ISSUER - + + + +com.r3corda.contracts.testing / DUMMY_CASH_ISSUER
+
+

DUMMY_CASH_ISSUER

+ +val DUMMY_CASH_ISSUER: PartyAndReference
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r_-k-e-y.html b/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r_-k-e-y.html new file mode 100644 index 0000000000..f1c444e9b9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-d-u-m-m-y_-c-a-s-h_-i-s-s-u-e-r_-k-e-y.html @@ -0,0 +1,15 @@ + + +DUMMY_CASH_ISSUER_KEY - + + + +com.r3corda.contracts.testing / DUMMY_CASH_ISSUER_KEY
+
+

DUMMY_CASH_ISSUER_KEY

+ +val DUMMY_CASH_ISSUER_KEY: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-c-a-s-h.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-c-a-s-h.html new file mode 100644 index 0000000000..fb4a97eee7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-c-a-s-h.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.CASH - + + + +com.r3corda.contracts.testing / JavaTestHelpers / CASH
+
+

CASH

+ +fun CASH(amount: Amount<Currency>): State
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n.html new file mode 100644 index 0000000000..442875f366 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.OBLIGATION - + + + +com.r3corda.contracts.testing / JavaTestHelpers / OBLIGATION
+
+

OBLIGATION

+ +fun OBLIGATION(amount: Amount<Issued<Currency>>): State<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html new file mode 100644 index 0000000000..75259dbb11 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.OBLIGATION_DEF - + + + +com.r3corda.contracts.testing / JavaTestHelpers / OBLIGATION_DEF
+
+

OBLIGATION_DEF

+ +fun OBLIGATION_DEF(issued: Issued<Currency>): StateTemplate<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-s-t-a-t-e.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-s-t-a-t-e.html new file mode 100644 index 0000000000..01f3c66dd8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/-s-t-a-t-e.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.STATE - + + + +com.r3corda.contracts.testing / JavaTestHelpers / STATE
+
+

STATE

+ +fun STATE(amount: Amount<Issued<Currency>>): State
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/at.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/at.html new file mode 100644 index 0000000000..7a51b70b8f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/at.html @@ -0,0 +1,17 @@ + + +JavaTestHelpers.at - + + + +com.r3corda.contracts.testing / JavaTestHelpers / at
+
+

at

+ +fun <T> at(state: State<T>, dueBefore: Instant): State<T>
+ +fun <T> at(issuanceDef: IssuanceDefinition<T>, dueBefore: Instant): IssuanceDefinition<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/between.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/between.html new file mode 100644 index 0000000000..7e0dd0d712 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/between.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.between - + + + +com.r3corda.contracts.testing / JavaTestHelpers / between
+
+

between

+ +fun <T> between(state: State<T>, parties: <ERROR CLASS><Party, PublicKey>): State<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/index.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/index.html new file mode 100644 index 0000000000..8633b86f4e --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/index.html @@ -0,0 +1,87 @@ + + +JavaTestHelpers - + + + +com.r3corda.contracts.testing / JavaTestHelpers
+
+

JavaTestHelpers

+object JavaTestHelpers
+
+
+

Functions

+
sumCashBy -fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>

Sums the cash states in the list belonging to a single owner, throwing an exception +fun Iterable<ContractState>.sumCashBy(owner: PublicKey): <ERROR CLASS>

Sums the cash states in the list belonging to a single owner, throwing an exception if there are none, or if any of the cash states cannot be added together (i.e. are different currencies).

sumCashOrZero -fun Iterable<ContractState>.sumCashOrZero(currency: Currency): <ERROR CLASS>

Sums the cash states in the list, returning zero of the given currency if there are none.

+fun Iterable<ContractState>.sumCashOrZero(currency: Currency): <ERROR CLASS>

Sums the cash states in the list, returning zero of the given currency if there are none.

sumFungibleBy -fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>

Sums the asset states in the list belonging to a single owner, throwing an exception +fun <T> Iterable<ContractState>.sumFungibleBy(owner: PublicKey): <ERROR CLASS>

Sums the asset states in the list belonging to a single owner, throwing an exception if there are none, or if any of the asset states cannot be added together (i.e. are different tokens).

sumFungibleOrZero -fun <T> Iterable<ContractState>.sumFungibleOrZero(token: T): <ERROR CLASS>

Sums the asset states in the list, returning zero of the given token if there are none.

+fun <T> Iterable<ContractState>.sumFungibleOrZero(token: T): <ERROR CLASS>

Sums the asset states in the list, returning zero of the given token if there are none.

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+CASH +fun CASH(amount: Amount<Currency>): State
+OBLIGATION +fun OBLIGATION(amount: Amount<Issued<Currency>>): State<Currency>
+OBLIGATION_DEF +fun OBLIGATION_DEF(issued: Issued<Currency>): StateTemplate<Currency>
+STATE +fun STATE(amount: Amount<Issued<Currency>>): State
+at +fun <T> at(state: State<T>, dueBefore: Instant): State<T>
+fun <T> at(issuanceDef: IssuanceDefinition<T>, dueBefore: Instant): IssuanceDefinition<T>
+between +fun <T> between(state: State<T>, parties: <ERROR CLASS><Party, PublicKey>): State<T>
+issuedBy +fun issuedBy(state: State, party: Party): State
+fun issuedBy(state: State, deposit: PartyAndReference): State
+fun <T> issuedBy(state: State<T>, party: Party): State<T>
+ownedBy +fun ownedBy(state: State, owner: PublicKey): State
+fun <T> ownedBy(state: State<T>, owner: PublicKey): State<T>
+fun ownedBy(state: State, owner: PublicKey): State
+fun ownedBy(state: <ERROR CLASS>, new_owner: PublicKey): <ERROR CLASS>
+withDeposit +fun withDeposit(state: State, deposit: PartyAndReference): State
+withNotary +fun withNotary(state: State, notary: Party): TransactionState<State>
+fun withNotary(state: State, notary: Party): TransactionState<State>
+fun withNotary(state: ContractState, notary: Party): TransactionState<ContractState>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/issued-by.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/issued-by.html new file mode 100644 index 0000000000..41c30bf9cf --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/issued-by.html @@ -0,0 +1,19 @@ + + +JavaTestHelpers.issuedBy - + + + +com.r3corda.contracts.testing / JavaTestHelpers / issuedBy
+
+

issuedBy

+ +fun issuedBy(state: State, party: Party): State
+ +fun issuedBy(state: State, deposit: PartyAndReference): State
+ +fun <T> issuedBy(state: State<T>, party: Party): State<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/owned-by.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/owned-by.html new file mode 100644 index 0000000000..862160230b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/owned-by.html @@ -0,0 +1,21 @@ + + +JavaTestHelpers.ownedBy - + + + +com.r3corda.contracts.testing / JavaTestHelpers / ownedBy
+
+

ownedBy

+ +fun ownedBy(state: State, owner: PublicKey): State
+ +fun <T> ownedBy(state: State<T>, owner: PublicKey): State<T>
+ +fun ownedBy(state: State, owner: PublicKey): State
+ +fun ownedBy(state: <ERROR CLASS>, new_owner: PublicKey): <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-deposit.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-deposit.html new file mode 100644 index 0000000000..b7187449e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-deposit.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.withDeposit - + + + +com.r3corda.contracts.testing / JavaTestHelpers / withDeposit
+
+

withDeposit

+ +fun withDeposit(state: State, deposit: PartyAndReference): State
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-notary.html b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-notary.html new file mode 100644 index 0000000000..e9b5ed42de --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-java-test-helpers/with-notary.html @@ -0,0 +1,19 @@ + + +JavaTestHelpers.withNotary - + + + +com.r3corda.contracts.testing / JavaTestHelpers / withNotary
+
+

withNotary

+ +fun withNotary(state: State, notary: Party): TransactionState<State>
+ +fun withNotary(state: State, notary: Party): TransactionState<State>
+ +fun withNotary(state: ContractState, notary: Party): TransactionState<ContractState>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n.html b/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n.html new file mode 100644 index 0000000000..309a73b291 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n.html @@ -0,0 +1,15 @@ + + +OBLIGATION - + + + +com.r3corda.contracts.testing / OBLIGATION
+
+

OBLIGATION

+ +val Amount<Issued<Currency>>.OBLIGATION: State<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html b/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html new file mode 100644 index 0000000000..5bd59f9d59 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-o-b-l-i-g-a-t-i-o-n_-d-e-f.html @@ -0,0 +1,16 @@ + + +OBLIGATION_DEF - + + + +com.r3corda.contracts.testing / OBLIGATION_DEF
+
+

OBLIGATION_DEF

+ +val Issued<Currency>.OBLIGATION_DEF: StateTemplate<Currency>
+

Allows you to write 100.DOLLARS.CASH

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/-s-t-a-t-e.html b/docs/build/html/api/com.r3corda.contracts.testing/-s-t-a-t-e.html new file mode 100644 index 0000000000..a9b452c60f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/-s-t-a-t-e.html @@ -0,0 +1,15 @@ + + +STATE - + + + +com.r3corda.contracts.testing / STATE
+
+

STATE

+ +val Amount<Issued<Currency>>.STATE: State
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/at.html b/docs/build/html/api/com.r3corda.contracts.testing/at.html new file mode 100644 index 0000000000..525f11dfc7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/at.html @@ -0,0 +1,17 @@ + + +at - + + + +com.r3corda.contracts.testing / at
+
+

at

+ +infix fun <T> State<T>.at(dueBefore: Instant): State<T>
+ +infix fun <T> IssuanceDefinition<T>.at(dueBefore: Instant): IssuanceDefinition<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/between.html b/docs/build/html/api/com.r3corda.contracts.testing/between.html new file mode 100644 index 0000000000..0e7f6f7c27 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/between.html @@ -0,0 +1,15 @@ + + +between - + + + +com.r3corda.contracts.testing / between
+
+

between

+ +infix fun <T> State<T>.between(parties: <ERROR CLASS><Party, PublicKey>): State<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/fill-with-some-test-cash.html b/docs/build/html/api/com.r3corda.contracts.testing/fill-with-some-test-cash.html new file mode 100644 index 0000000000..37efa769e1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/fill-with-some-test-cash.html @@ -0,0 +1,25 @@ + + +fillWithSomeTestCash - + + + +com.r3corda.contracts.testing / fillWithSomeTestCash
+
+

fillWithSomeTestCash

+ +fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>, notary: Party = DUMMY_NOTARY, atLeastThisManyStates: Int = 3, atMostThisManyStates: Int = 10, rng: Random = Random(), ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 0 }))): Wallet
+

Creates a random set of between (by default) 3 and 10 cash states that add up to the given amount and adds them +to the wallet. This is intended for unit tests.

+

The cash is self issued with the current nodes identity, as fetched from the storage service. Thus it +would not be trusted by any sensible market participant and is effectively an IOU. If it had been issued by +the central bank, well ... thatd be a different story altogether.

+

The service hub needs to provide at least a key management service and a storage service.

+
+
+

Return
+a wallet object that represents the generated states (it will NOT be the full wallet from the service hub)

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/generate-state.html b/docs/build/html/api/com.r3corda.contracts.testing/generate-state.html index 4d78aeb3c8..13957b9ee1 100644 --- a/docs/build/html/api/com.r3corda.contracts.testing/generate-state.html +++ b/docs/build/html/api/com.r3corda.contracts.testing/generate-state.html @@ -7,8 +7,8 @@ com.r3corda.contracts.testing / generateState

generateState

- -fun generateState(notary: Party = DUMMY_NOTARY): State
+ +fun generateState(): DummyState


diff --git a/docs/build/html/api/com.r3corda.contracts.testing/index.html b/docs/build/html/api/com.r3corda.contracts.testing/index.html index 0b5757ab5d..7529ac4e35 100644 --- a/docs/build/html/api/com.r3corda.contracts.testing/index.html +++ b/docs/build/html/api/com.r3corda.contracts.testing/index.html @@ -7,6 +7,17 @@ com.r3corda.contracts.testing

Package com.r3corda.contracts.testing

+

Types

+ + + + + + + +
+JavaTestHelpers +object JavaTestHelpers

Properties

@@ -14,7 +25,39 @@ +val Amount<Currency>.CASH: State

Allows you to write 100.DOLLARS.CASH

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +fun generateState(): DummyState +infix fun State.issued by(party: Party): State
+infix fun State.issued by(deposit: PartyAndReference): State
+infix fun <T> State<T>.issued by(party: Party): State<T> + + + + + + + +
CASH -val Amount<Currency>.CASH: State
+DUMMY_CASH_ISSUER +val DUMMY_CASH_ISSUER: PartyAndReference
+DUMMY_CASH_ISSUER_KEY +val DUMMY_CASH_ISSUER_KEY: <ERROR CLASS>
+OBLIGATION +val Amount<Issued<Currency>>.OBLIGATION: State<Currency>
+OBLIGATION_DEF +val Issued<Currency>.OBLIGATION_DEF: StateTemplate<Currency>

Allows you to write 100.DOLLARS.CASH

+
+STATE +val Amount<Issued<Currency>>.STATE: State
@@ -29,24 +72,62 @@
+at +infix fun <T> State<T>.at(dueBefore: Instant): State<T>
+infix fun <T> IssuanceDefinition<T>.at(dueBefore: Instant): IssuanceDefinition<T>
+between +infix fun <T> State<T>.between(parties: <ERROR CLASS><Party, PublicKey>): State<T>
+fillWithSomeTestCash +fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>, notary: Party = DUMMY_NOTARY, atLeastThisManyStates: Int = 3, atMostThisManyStates: Int = 10, rng: Random = Random(), ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 0 }))): Wallet

Creates a random set of between (by default) 3 and 10 cash states that add up to the given amount and adds them +to the wallet. This is intended for unit tests.

+
generateState -fun generateState(notary: Party = DUMMY_NOTARY): State
issued by -infix fun State.issued by(party: Party): State
owned by -infix fun State.owned by(owner: PublicKey): State
-infix fun State.owned by(owner: PublicKey): State
+infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
+infix fun <T> State<T>.owned by(owner: PublicKey): <ERROR CLASS>
+infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
infix fun <ERROR CLASS>.owned by(new_owner: PublicKey): <ERROR CLASS>
+with deposit +infix fun State.with deposit(deposit: PartyAndReference): State
+with notary +infix fun State.with notary(notary: Party): TransactionState<State>
+infix fun State.with notary(notary: Party): TransactionState<State>
+infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
diff --git a/docs/build/html/api/com.r3corda.contracts.testing/issued by.html b/docs/build/html/api/com.r3corda.contracts.testing/issued by.html index 22c2c6ca4b..4ddc7a89ae 100644 --- a/docs/build/html/api/com.r3corda.contracts.testing/issued by.html +++ b/docs/build/html/api/com.r3corda.contracts.testing/issued by.html @@ -7,8 +7,12 @@ com.r3corda.contracts.testing / issued by

issued by

- -infix fun State.issued by(party: Party): State
+ +infix fun State.issued by(party: Party): State
+ +infix fun State.issued by(deposit: PartyAndReference): State
+ +infix fun <T> State<T>.issued by(party: Party): State<T>


diff --git a/docs/build/html/api/com.r3corda.contracts.testing/owned by.html b/docs/build/html/api/com.r3corda.contracts.testing/owned by.html index 2f3420c01e..cbf4d09ddf 100644 --- a/docs/build/html/api/com.r3corda.contracts.testing/owned by.html +++ b/docs/build/html/api/com.r3corda.contracts.testing/owned by.html @@ -7,10 +7,12 @@ com.r3corda.contracts.testing / owned by

owned by

- -infix fun State.owned by(owner: PublicKey): State
+ +infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
+ +infix fun <T> State<T>.owned by(owner: PublicKey): <ERROR CLASS>
-infix fun State.owned by(owner: PublicKey): State
+infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
infix fun <ERROR CLASS>.owned by(new_owner: PublicKey): <ERROR CLASS>

diff --git a/docs/build/html/api/com.r3corda.contracts.testing/with deposit.html b/docs/build/html/api/com.r3corda.contracts.testing/with deposit.html new file mode 100644 index 0000000000..ec178280e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/with deposit.html @@ -0,0 +1,15 @@ + + +with deposit - + + + +com.r3corda.contracts.testing / with deposit
+
+

with deposit

+ +infix fun State.with deposit(deposit: PartyAndReference): State
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.testing/with notary.html b/docs/build/html/api/com.r3corda.contracts.testing/with notary.html new file mode 100644 index 0000000000..e3ce4a77ac --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.testing/with notary.html @@ -0,0 +1,19 @@ + + +with notary - + + + +com.r3corda.contracts.testing / with notary
+
+

with notary

+ +infix fun State.with notary(notary: Party): TransactionState<State>
+ +infix fun State.with notary(notary: Party): TransactionState<State>
+ +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/-init-.html index 5a7cb07409..c26f5d22d2 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / State / <init>

<init>

-State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party)
+State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Issued<Currency>>, maturityDate: Instant)


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/contract.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/contract.html index e86a6a1146..2be4b05310 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/contract.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/contract.html @@ -10,7 +10,33 @@ val contract: CommercialPaper
Overrides ContractState.contract
-

Contract by which the state belongs

+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/face-value.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/face-value.html index b03d33e1d5..d39247b8d5 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/face-value.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/face-value.html @@ -8,7 +8,7 @@

faceValue

-val faceValue: Amount<Currency>
+val faceValue: Amount<Issued<Currency>>


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/index.html index 8fd8f29de4..2f43e427f5 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/index.html @@ -17,7 +17,7 @@ <init> -State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party) +State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Issued<Currency>>, maturityDate: Instant) @@ -28,14 +28,14 @@ contract -val contract: CommercialPaper

Contract by which the state belongs

+val contract: CommercialPaper

An instance of the contract class that will verify this state.

faceValue -val faceValue: Amount<Currency> +val faceValue: Amount<Issued<Currency>> @@ -51,16 +51,16 @@ -notary +owner -val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

-owner +participants -val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

@@ -78,7 +78,7 @@ withFaceValue -fun withFaceValue(newFaceValue: Amount<Currency>): <ERROR CLASS> +fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): <ERROR CLASS> @@ -120,7 +120,13 @@ owned by -infix fun State.owned by(owner: PublicKey): State +infix fun State.owned by(owner: PublicKey): <ERROR CLASS> + + + +with notary + +infix fun State.with notary(notary: Party): TransactionState<State> diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/participants.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/participants.html new file mode 100644 index 0000000000..272c1e6369 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/participants.html @@ -0,0 +1,34 @@ + + +CommercialPaper.State.participants - + + + +com.r3corda.contracts / CommercialPaper / State / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/with-face-value.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/with-face-value.html index d56566210a..91c20287dc 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/with-face-value.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-state/with-face-value.html @@ -7,8 +7,8 @@ com.r3corda.contracts / CommercialPaper / State / withFaceValue

withFaceValue

- -fun withFaceValue(newFaceValue: Amount<Currency>): <ERROR CLASS>
+ +fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): <ERROR CLASS>


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-issue.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-issue.html index 29b7f9c950..07cd5611bf 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-issue.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-issue.html @@ -7,8 +7,8 @@ com.r3corda.contracts / CommercialPaper / generateIssue

generateIssue

- -fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party): TransactionBuilder
+ +fun generateIssue(faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder

Returns a transaction that issues commercial paper, owned by the issuing parties key. Does not update an existing transaction because you arent able to issue multiple pieces of CP in a single transaction at the moment: this restriction is not fundamental and may be lifted later.

diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-redeem.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-redeem.html index 210b83543f..b2e06b2a4a 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-redeem.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/generate-redeem.html @@ -7,8 +7,8 @@ com.r3corda.contracts / CommercialPaper / generateRedeem

generateRedeem

- -fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit
+ +fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit

Intended to be called by the issuer of some commercial paper, when an owner has notified us that they wish to redeem the paper. We must therefore send enough money to the key that owns the paper to satisfy the face value, and then ensure the paper is removed from the ledger.

diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/index.html index 953611e3f8..cf067f4164 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/index.html @@ -58,7 +58,7 @@ the contracts contents).

generateIssue -fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party): TransactionBuilder

Returns a transaction that issues commercial paper, owned by the issuing parties key. Does not update +fun generateIssue(faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder

Returns a transaction that issues commercial paper, owned by the issuing parties key. Does not update an existing transaction because you arent able to issue multiple pieces of CP in a single transaction at the moment: this restriction is not fundamental and may be lifted later.

@@ -74,7 +74,7 @@ at the moment: this restriction is not fundamental and may be lifted later.

generateRedeem -fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit

Intended to be called by the issuer of some commercial paper, when an owner has notified us that they wish +fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit

Intended to be called by the issuer of some commercial paper, when an owner has notified us that they wish to redeem the paper. We must therefore send enough money to the key that owns the paper to satisfy the face value, and then ensure the paper is removed from the ledger.

@@ -83,7 +83,7 @@ value, and then ensure the paper is removed from the ledger.

verify -fun verify(tx: TransactionForVerification): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. +fun verify(tx: TransactionForContract): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object rather than an argument so that additional data can be added without breaking binary compatibility with existing contract code.

diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/verify.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/verify.html index a8099f0d09..56ce4ec630 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/verify.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/verify.html @@ -7,8 +7,8 @@ com.r3corda.contracts / CommercialPaper / verify

verify

- -fun verify(tx: TransactionForVerification): Unit
+ +fun verify(tx: TransactionForContract): Unit
Overrides Contract.verify

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object diff --git a/docs/build/html/api/com.r3corda.contracts/-fixed-rate/hash-code.html b/docs/build/html/api/com.r3corda.contracts/-fixed-rate/hash-code.html index 951e1e4acf..84764d7c6c 100644 --- a/docs/build/html/api/com.r3corda.contracts/-fixed-rate/hash-code.html +++ b/docs/build/html/api/com.r3corda.contracts/-fixed-rate/hash-code.html @@ -10,10 +10,10 @@ fun hashCode(): Int
Overrides Rate.hashCode
-Returns
+

Returns
the hash code of the ratioUnit or zero if the ratioUnit is null, as is the case for floating rate fixings that have not yet happened. Yet-to-be fixed floating rates need to be equal such that schedules can be tested -for equality.
+for equality.



diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-calculation/next-fixing-date.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-calculation/next-fixing-date.html index 186db672bc..52cb69daf2 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-calculation/next-fixing-date.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-calculation/next-fixing-date.html @@ -10,8 +10,8 @@ fun nextFixingDate(): LocalDate?

Gets the date of the next fixing.

-Return
-LocalDate or null if no more fixings.
+

Return
+LocalDate or null if no more fixings.



diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/-init-.html index 8c445d37fd..f2461c6d4c 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / InterestRateSwap / FloatingLeg / <init>

<init>

-FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriod: DateOffset, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)
+FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriodOffset: Int, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)


diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/copy.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/copy.html index 067f666975..ddcd0d5059 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/copy.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/copy.html @@ -7,8 +7,8 @@ com.r3corda.contracts / InterestRateSwap / FloatingLeg / copy

copy

- -fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: DateOffset = this.fixingPeriod, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg
+ +fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: Int = this.fixingPeriodOffset, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg


diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/fixing-period-offset.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/fixing-period-offset.html new file mode 100644 index 0000000000..f5e296f814 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/fixing-period-offset.html @@ -0,0 +1,15 @@ + + +InterestRateSwap.FloatingLeg.fixingPeriodOffset - + + + +com.r3corda.contracts / InterestRateSwap / FloatingLeg / fixingPeriodOffset
+
+

fixingPeriodOffset

+ +var fixingPeriodOffset: Int
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/index.html index 15799fb581..8f1d4d245b 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-floating-leg/index.html @@ -17,7 +17,7 @@ <init> -FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriod: DateOffset, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor) +FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriodOffset: Int, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor) @@ -32,9 +32,9 @@ -fixingPeriod +fixingPeriodOffset -var fixingPeriod: DateOffset +var fixingPeriodOffset: Int @@ -182,7 +182,7 @@ copy -fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: DateOffset = this.fixingPeriod, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg +fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: Int = this.fixingPeriodOffset, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/-init-.html index 5d13246b7f..1da59b7898 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / InterestRateSwap / State / <init>

<init>

-State(fixedLeg: FixedLeg, floatingLeg: FloatingLeg, calculation: Calculation, common: Common, notary: Party)
+State(fixedLeg: FixedLeg, floatingLeg: FloatingLeg, calculation: Calculation, common: Common)

The state class contains the 4 major data classes



diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/contract.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/contract.html index 3d5e0e1950..2e7a758a69 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/contract.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/contract.html @@ -10,7 +10,33 @@ val contract: InterestRateSwap
Overrides ContractState.contract
-

Contract by which the state belongs

+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+


diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-agreement.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-agreement.html index 21012e412e..a5cd1cce3b 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-agreement.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-agreement.html @@ -7,8 +7,8 @@ com.r3corda.contracts / InterestRateSwap / State / generateAgreement

generateAgreement

- -fun generateAgreement(): TransactionBuilder
+ +fun generateAgreement(notary: Party): TransactionBuilder
Overrides DealState.generateAgreement

Generate a partial transaction representing an agreement (command) to this deal, allowing a general deal/agreement protocol to generate the necessary transaction for potential implementations

diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-fix.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-fix.html index a468f1a5ef..785167dc50 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-fix.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/generate-fix.html @@ -7,8 +7,8 @@ com.r3corda.contracts / InterestRateSwap / State / generateFix

generateFix

- -fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix): Unit
+ +fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix): Unit
Overrides FixableDealState.generateFix

Generate a fixing command for this deal and fix

TODO: This would also likely move to methods on the Contract once the changes to reference diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/index.html index 9321412cb0..654a8698a0 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / InterestRateSwap / State

State

-data class State : FixableDealState
+data class State : FixableDealState, SchedulableState

The state class contains the 4 major data classes



@@ -18,7 +18,7 @@ <init> -State(fixedLeg: FixedLeg, floatingLeg: FloatingLeg, calculation: Calculation, common: Common, notary: Party)

The state class contains the 4 major data classes

+State(fixedLeg: FixedLeg, floatingLeg: FloatingLeg, calculation: Calculation, common: Common)

The state class contains the 4 major data classes

@@ -42,7 +42,7 @@ contract -val contract: InterestRateSwap

Contract by which the state belongs

+val contract: InterestRateSwap

An instance of the contract class that will verify this state.

@@ -59,9 +59,9 @@ -notary +participants -val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

@@ -101,7 +101,7 @@ generateAgreement -fun generateAgreement(): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general +fun generateAgreement(notary: Party): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general deal/agreement protocol to generate the necessary transaction for potential implementations

@@ -109,7 +109,7 @@ deal/agreement protocol to generate the necessary transaction for potential impl generateFix -fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix): Unit

Generate a fixing command for this deal and fix

+fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix): Unit

Generate a fixing command for this deal and fix

@@ -128,6 +128,15 @@ deal/agreement protocol to generate the necessary transaction for potential impl +nextScheduledActivity + +fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity?

Indicate whether there is some activity to be performed at some future point in time with respect to this +ContractState, what that activity is and at what point in time it should be initiated. +This can be used to implement deadlines for payment or processing of financial instruments according to a schedule.

+ + + + prettyPrint fun prettyPrint(): String

Just makes printing it out a bit better for those who dont have 80000 column wide monitors.

diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-fixing-of.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-fixing-of.html index 18b940ebf8..4df36de499 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-fixing-of.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-fixing-of.html @@ -11,9 +11,6 @@ fun nextFixingOf(): FixOf?
Overrides FixableDealState.nextFixingOf

When is the next fixing and what is the fixing for?

-

TODO: In future we would use this to register for an event to trigger a/the fixing protocol

-
-


diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-scheduled-activity.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-scheduled-activity.html new file mode 100644 index 0000000000..f50a274e78 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/next-scheduled-activity.html @@ -0,0 +1,24 @@ + + +InterestRateSwap.State.nextScheduledActivity - + + + +com.r3corda.contracts / InterestRateSwap / State / nextScheduledActivity
+
+

nextScheduledActivity

+ +fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity?
+Overrides SchedulableState.nextScheduledActivity
+

Indicate whether there is some activity to be performed at some future point in time with respect to this +ContractState, what that activity is and at what point in time it should be initiated. +This can be used to implement deadlines for payment or processing of financial instruments according to a schedule.

+

The state has no reference to its own StateRef, so supply that for use as input to any ProtocolLogic constructed.

+
+
+

Return
+null if there is no activity to schedule

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/participants.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/participants.html new file mode 100644 index 0000000000..1de142b7c2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/participants.html @@ -0,0 +1,34 @@ + + +InterestRateSwap.State.participants - + + + +com.r3corda.contracts / InterestRateSwap / State / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/parties.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/parties.html index c6ad978be4..9eb43a3855 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/parties.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-state/parties.html @@ -11,9 +11,9 @@ val parties: Array<Party>
Overrides DealState.parties

Exposes the Parties involved in a generic way

-Getter
+

Getter

Exposes the Parties involved in a generic way

-
+



diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/index.html index 454c3d0700..3dc096f1c6 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/index.html @@ -62,7 +62,7 @@ copy / update for each transition)

State -data class State : FixableDealState

The state class contains the 4 major data classes

+data class State : FixableDealState, SchedulableState

The state class contains the 4 major data classes

@@ -148,7 +148,7 @@ Note: The day count, interest rate calculation etc are not finished yet, but the verify -fun verify(tx: TransactionForVerification): Unit

verify() with some examples of what needs to be checked.

+fun verify(tx: TransactionForContract): Unit

verify() with some examples of what needs to be checked.

diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/verify.html index ea5638a19b..47b4b4b77d 100644 --- a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/verify.html +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/verify.html @@ -7,8 +7,8 @@ com.r3corda.contracts / InterestRateSwap / verify

verify

- -fun verify(tx: TransactionForVerification): Unit
+ +fun verify(tx: TransactionForContract): Unit
Overrides Contract.verify

verify() with some examples of what needs to be checked.


diff --git a/docs/build/html/api/com.r3corda.contracts/-rate/hash-code.html b/docs/build/html/api/com.r3corda.contracts/-rate/hash-code.html index 3827fa867d..e48fba36d8 100644 --- a/docs/build/html/api/com.r3corda.contracts/-rate/hash-code.html +++ b/docs/build/html/api/com.r3corda.contracts/-rate/hash-code.html @@ -9,10 +9,10 @@

hashCode

open fun hashCode(): Int
-Returns
+

Returns
the hash code of the ratioUnit or zero if the ratioUnit is null, as is the case for floating rate fixings that have not yet happened. Yet-to-be fixed floating rates need to be equal such that schedules can be tested -for equality.
+for equality.



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-amount/index.html b/docs/build/html/api/com.r3corda.core.contracts/-amount/index.html index 3e3ab1924a..e3aaaf3f4f 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-amount/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-amount/index.html @@ -108,7 +108,20 @@ amount used in whatever underlying thing the amount represents.

CASH -val Amount<Currency>.CASH: State +val Amount<Currency>.CASH: State

Allows you to write 100.DOLLARS.CASH

+ + + + +OBLIGATION + +val Amount<Issued<Currency>>.OBLIGATION: State<Currency> + + + +STATE + +val Amount<Issued<Currency>>.STATE: State @@ -117,6 +130,12 @@ amount used in whatever underlying thing the amount represents.

+issued by + +infix fun Amount<Currency>.issued by(deposit: PartyAndReference): Amount<Issued<Currency>> + + + times operator fun Amount<Currency>.times(other: RatioUnit): Amount<Currency> diff --git a/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/bilateral-net-state.html b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/bilateral-net-state.html new file mode 100644 index 0000000000..35adc0bcb8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/bilateral-net-state.html @@ -0,0 +1,17 @@ + + +BilateralNettableState.bilateralNetState - + + + +com.r3corda.core.contracts / BilateralNettableState / bilateralNetState
+
+

bilateralNetState

+ +abstract val bilateralNetState: Any
+

Returns an object used to determine if two states can be subject to close-out netting. If two states return +equal objects, they can be close out netted together.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/index.html new file mode 100644 index 0000000000..6d606cd40e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/index.html @@ -0,0 +1,55 @@ + + +BilateralNettableState - + + + +com.r3corda.core.contracts / BilateralNettableState
+
+

BilateralNettableState

+interface BilateralNettableState<T : BilateralNettableState<T>>
+

Interface for state objects that support being netted with other state objects.

+
+
+

Properties

+ + + + + + + +
+bilateralNetState +abstract val bilateralNetState: Any

Returns an object used to determine if two states can be subject to close-out netting. If two states return +equal objects, they can be close out netted together.

+
+

Functions

+ + + + + + + +
+net +abstract fun net(other: T): T

Perform bilateral netting of this state with another state. The two states must be compatible (as in +bilateralNetState objects are equal).

+
+

Inheritors

+ + + + + + + +
+State +data class State<P> : FungibleAssetState<P, IssuanceDefinition<P>>, BilateralNettableState<State<P>>

A state representing the obligation of one party (obligor) to deliver a specified number of +units of an underlying asset (described as issuanceDef.acceptableIssuedProducts) to the beneficiary +no later than the specified time.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/net.html b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/net.html new file mode 100644 index 0000000000..2aa96c4673 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-bilateral-nettable-state/net.html @@ -0,0 +1,17 @@ + + +BilateralNettableState.net - + + + +com.r3corda.core.contracts / BilateralNettableState / net
+
+

net

+ +abstract fun net(other: T): T
+

Perform bilateral netting of this state with another state. The two states must be compatible (as in +bilateralNetState objects are equal).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-command-data.html b/docs/build/html/api/com.r3corda.core.contracts/-command-data.html index 043de5756c..f56b527e26 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-command-data.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-command-data.html @@ -22,13 +22,19 @@ -Commands +Commands interface Commands : CommandData -Commands +Commands + +interface Commands : CommandData + + + +Commands interface Commands : CommandData @@ -53,6 +59,27 @@ +IssuanceCommands + +interface IssuanceCommands<P> : CommandData

Interface for commands that apply to states grouped by issuance definition

+ + + + +IssueCommand + +interface IssueCommand : CommandData

A common issue command, to enforce that issue commands have a nonce value.

+ + + + +MoveCommand + +interface MoveCommand : CommandData

A common move command for contracts which can change owner.

+ + + + TimestampCommand data class TimestampCommand : CommandData

If present in a transaction, contains a time that was verified by the timestamping authority/authorities whose diff --git a/docs/build/html/api/com.r3corda.core.contracts/-contract-state/contract.html b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/contract.html index 1cbd33ae28..582b5c58ad 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-contract-state/contract.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/contract.html @@ -9,7 +9,33 @@

contract

abstract val contract: Contract
-

Contract by which the state belongs

+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-contract-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/index.html index b9f59297fd..13803bb336 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-contract-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/index.html @@ -10,7 +10,9 @@ interface ContractState

A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk file that the program can use to persist data across transactions. States are immutable: once created they are never -updated, instead, any changes must generate a new successor state.

+updated, instead, any changes must generate a new successor state. States can be updated (consumed) only once: the +notary is responsible for ensuring there is no "double spending" by only signing a transaction if the input states +are all free.



Properties

@@ -20,14 +22,14 @@ updated, instead, any changes must generate a new successor state.

contract -abstract val contract: Contract

Contract by which the state belongs

+abstract val contract: Contract

An instance of the contract class that will verify this state.

-notary +participants -abstract val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+abstract val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

@@ -44,9 +46,9 @@ updated, instead, any changes must generate a new successor state.

-label +with notary -infix fun ContractState.label(label: String): LabeledOutput +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState> @@ -55,6 +57,13 @@ updated, instead, any changes must generate a new successor state.

+DummyState + +data class DummyState : ContractState

Dummy state for use in testing. Not part of any real contract.

+ + + + LinearState interface LinearState : ContractState

A state that evolves by superseding itself, all of which share the common "thread"

@@ -62,6 +71,15 @@ updated, instead, any changes must generate a new successor state.

+MultiOwnerState + +data class MultiOwnerState : ContractState, State

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+ + + + OwnableState interface OwnableState : ContractState

A contract state that can have a single owner.

@@ -69,9 +87,15 @@ updated, instead, any changes must generate a new successor state.

+SchedulableState + +interface SchedulableState : ContractState + + + State -class State : ContractState +interface State : ContractState diff --git a/docs/build/html/api/com.r3corda.core.contracts/-contract-state/participants.html b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/participants.html new file mode 100644 index 0000000000..f9fb2b13ec --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-contract-state/participants.html @@ -0,0 +1,24 @@ + + +ContractState.participants - + + + +com.r3corda.core.contracts / ContractState / participants
+
+

participants

+ +abstract val participants: List<PublicKey>
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-contract/index.html b/docs/build/html/api/com.r3corda.core.contracts/-contract/index.html index 739580dce6..07a0ccaa50 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-contract/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-contract/index.html @@ -34,7 +34,7 @@ the contracts contents).

verify -abstract fun verify(tx: TransactionForVerification): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. +abstract fun verify(tx: TransactionForContract): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object rather than an argument so that additional data can be added without breaking binary compatibility with existing contract code.

@@ -47,6 +47,12 @@ existing contract code.

+AlwaysSucceedContract + +class AlwaysSucceedContract : Contract + + + CommercialPaper class CommercialPaper : Contract @@ -59,7 +65,7 @@ existing contract code.

-FungibleAsset +FungibleAsset abstract class FungibleAsset<T> : Contract

Superclass for contracts representing assets which are fungible, countable and issued by a specific party. States contain assets which are equivalent (such as cash of the same currency), so records of their existence can @@ -80,6 +86,16 @@ Currently, we are not interested (excuse pun) in valuing the swap, calculating t This is just a representation of a vanilla Fixed vs Floating (same currency) IRS in the R3 prototype model.

+ + +Obligation + +class Obligation<P> : Contract

An obligation contract commits the obligor to delivering a specified amount of a fungible asset (for example the +Cash contract) at a specified future point in time. Settlement transactions may split and merge contracts across +multiple input and output states. The goal of this design is to handle amounts owed, and these contracts are expected +to be netted/merged, with settlement only for any remainder amount.

+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-contract/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-contract/verify.html index b45eb13e63..cf45cf2a45 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-contract/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-contract/verify.html @@ -7,8 +7,8 @@ com.r3corda.core.contracts / Contract / verify

verify

- -abstract fun verify(tx: TransactionForVerification): Unit
+ +abstract fun verify(tx: TransactionForContract): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object rather than an argument so that additional data can be added without breaking binary compatibility with diff --git a/docs/build/html/api/com.r3corda.core.contracts/-deal-state/generate-agreement.html b/docs/build/html/api/com.r3corda.core.contracts/-deal-state/generate-agreement.html index 058b03e792..84717d321b 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-deal-state/generate-agreement.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-deal-state/generate-agreement.html @@ -7,8 +7,8 @@ com.r3corda.core.contracts / DealState / generateAgreement

generateAgreement

- -abstract fun generateAgreement(): TransactionBuilder
+ +abstract fun generateAgreement(notary: Party): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general deal/agreement protocol to generate the necessary transaction for potential implementations

TODO: Currently this is the "inception" transaction but in future an offer of some description might be an input state ref

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-deal-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-deal-state/index.html index 82c521ac03..19e34116b6 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-deal-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-deal-state/index.html @@ -50,7 +50,7 @@ implementation of general protocols that manipulate many agreement types.

generateAgreement -abstract fun generateAgreement(): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general +abstract fun generateAgreement(notary: Party): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general deal/agreement protocol to generate the necessary transaction for potential implementations

@@ -86,9 +86,9 @@ deal/agreement protocol to generate the necessary transaction for potential impl -label +with notary -infix fun ContractState.label(label: String): LabeledOutput +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState> diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/-init-.html new file mode 100644 index 0000000000..942f3076f1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/-init-.html @@ -0,0 +1,14 @@ + + +DummyContract.Commands.Move.<init> - + + + +com.r3corda.core.contracts / DummyContract / Commands / Move / <init>
+
+

<init>

+Move()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/index.html new file mode 100644 index 0000000000..7bba4256d4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/-move/index.html @@ -0,0 +1,42 @@ + + +DummyContract.Commands.Move - + + + +com.r3corda.core.contracts / DummyContract / Commands / Move
+
+

Move

+class Move : TypeOnlyCommandData, Commands
+
+
+

Constructors

+ + + + + + + +
+<init> +Move()
+

Inherited Functions

+ + + + + + + + + + + +
+equals +open fun equals(other: Any?): Boolean
+hashCode +open fun hashCode(): <ERROR CLASS>
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/index.html index 9cf330e87f..603df19645 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-commands/index.html @@ -19,6 +19,12 @@ class Create : TypeOnlyCommandData, Commands + + +Move + +class Move : TypeOnlyCommandData, Commands +

Inheritors

@@ -30,6 +36,12 @@ class Create : TypeOnlyCommandData, Commands + + +Move + +class Move : TypeOnlyCommandData, Commands + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/-init-.html new file mode 100644 index 0000000000..89eb0ee891 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/-init-.html @@ -0,0 +1,17 @@ + + +DummyContract.MultiOwnerState.<init> - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState / <init>
+
+

<init>

+MultiOwnerState(magicNumber: Int = 0, owners: List<PublicKey>)
+

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/contract.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/contract.html new file mode 100644 index 0000000000..ae60f276aa --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/contract.html @@ -0,0 +1,43 @@ + + +DummyContract.MultiOwnerState.contract - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState / contract
+
+

contract

+ +val contract: DummyContract
+Overrides ContractState.contract
+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/index.html new file mode 100644 index 0000000000..992cfaf685 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/index.html @@ -0,0 +1,62 @@ + + +DummyContract.MultiOwnerState - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState
+
+

MultiOwnerState

+data class MultiOwnerState : ContractState, State
+

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+
+
+

Constructors

+ + + + + + + +
+<init> +MultiOwnerState(magicNumber: Int = 0, owners: List<PublicKey>)

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + +
+contract +val contract: DummyContract

An instance of the contract class that will verify this state.

+
+magicNumber +val magicNumber: Int
+owners +val owners: List<PublicKey>
+participants +val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/magic-number.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/magic-number.html new file mode 100644 index 0000000000..cfea75b093 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/magic-number.html @@ -0,0 +1,16 @@ + + +DummyContract.MultiOwnerState.magicNumber - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState / magicNumber
+
+

magicNumber

+ +val magicNumber: Int
+Overrides State.magicNumber
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/owners.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/owners.html new file mode 100644 index 0000000000..f18d145d44 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/owners.html @@ -0,0 +1,15 @@ + + +DummyContract.MultiOwnerState.owners - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState / owners
+
+

owners

+ +val owners: List<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/participants.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/participants.html new file mode 100644 index 0000000000..202d1c290a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-multi-owner-state/participants.html @@ -0,0 +1,34 @@ + + +DummyContract.MultiOwnerState.participants - + + + +com.r3corda.core.contracts / DummyContract / MultiOwnerState / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/-init-.html new file mode 100644 index 0000000000..0567f7f489 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/-init-.html @@ -0,0 +1,14 @@ + + +DummyContract.SingleOwnerState.<init> - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / <init>
+
+

<init>

+SingleOwnerState(magicNumber: Int = 0, owner: PublicKey)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/contract.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/contract.html new file mode 100644 index 0000000000..93e4007a60 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/contract.html @@ -0,0 +1,43 @@ + + +DummyContract.SingleOwnerState.contract - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / contract
+
+

contract

+ +val contract: DummyContract
+Overrides ContractState.contract
+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/index.html new file mode 100644 index 0000000000..786b6ad714 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/index.html @@ -0,0 +1,69 @@ + + +DummyContract.SingleOwnerState - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState
+
+

SingleOwnerState

+data class SingleOwnerState : OwnableState, State
+
+
+

Constructors

+ + + + + + + +
+<init> +SingleOwnerState(magicNumber: Int = 0, owner: PublicKey)
+

Properties

+ + + + + + + + + + + + + + + + + + + +
+contract +val contract: DummyContract

An instance of the contract class that will verify this state.

+
+magicNumber +val magicNumber: Int
+owner +val owner: PublicKey

There must be a MoveCommand signed by this key to claim the amount

+
+participants +val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+

Functions

+ + + + + + + +
+withNewOwner +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/magic-number.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/magic-number.html new file mode 100644 index 0000000000..eec96bb510 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/magic-number.html @@ -0,0 +1,16 @@ + + +DummyContract.SingleOwnerState.magicNumber - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / magicNumber
+
+

magicNumber

+ +val magicNumber: Int
+Overrides State.magicNumber
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/owner.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/owner.html new file mode 100644 index 0000000000..18fcc198a4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/owner.html @@ -0,0 +1,17 @@ + + +DummyContract.SingleOwnerState.owner - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / owner
+
+

owner

+ +val owner: PublicKey
+Overrides OwnableState.owner
+

There must be a MoveCommand signed by this key to claim the amount

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/participants.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/participants.html new file mode 100644 index 0000000000..6aa4a749ff --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/participants.html @@ -0,0 +1,34 @@ + + +DummyContract.SingleOwnerState.participants - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/with-new-owner.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/with-new-owner.html new file mode 100644 index 0000000000..02aa59fb8b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-single-owner-state/with-new-owner.html @@ -0,0 +1,17 @@ + + +DummyContract.SingleOwnerState.withNewOwner - + + + +com.r3corda.core.contracts / DummyContract / SingleOwnerState / withNewOwner
+
+

withNewOwner

+ +fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
+Overrides OwnableState.withNewOwner
+

Copies the underlying data structure, replacing the owner field with this new value and leaving the rest alone

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/index.html index 7bc8c4b5b8..77c1761623 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/index.html @@ -7,44 +7,58 @@ com.r3corda.core.contracts / DummyContract / State

State

-class State : ContractState
+interface State : ContractState


-

Constructors

- - - - - - - -
-<init> -State(magicNumber: Int = 0, notary: Party)

Properties

- - - - +abstract val magicNumber: Int + + +
-contract -val contract: DummyContract

Contract by which the state belongs

-
magicNumber -val magicNumber: Int
+

Inherited Properties

+ + + + + +participants
+contract +abstract val contract: Contract

An instance of the contract class that will verify this state.

+
-notary -val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+abstract val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+

Inheritors

+ + + + + + + + + + + +
+MultiOwnerState +data class MultiOwnerState : ContractState, State

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+
+SingleOwnerState +data class SingleOwnerState : OwnableState, State
diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/magic-number.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/magic-number.html index b7d5b7bde7..d7a05c8850 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/magic-number.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/-state/magic-number.html @@ -8,7 +8,7 @@

magicNumber

-val magicNumber: Int
+abstract val magicNumber: Int


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/index.html index e16c974ef7..707d589a3d 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/index.html @@ -21,9 +21,24 @@ +MultiOwnerState + +data class MultiOwnerState : ContractState, State

Alternative state with multiple owners. This exists primarily to provide a dummy state with multiple +participants, and could in theory be merged with SingleOwnerState by putting the additional participants +in a different field, however this is a good example of a contract with multiple states.

+ + + + +SingleOwnerState + +data class SingleOwnerState : OwnableState, State + + + State -class State : ContractState +interface State : ContractState @@ -64,7 +79,7 @@ the contracts contents).

verify -fun verify(tx: TransactionForVerification): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. +fun verify(tx: TransactionForContract): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object rather than an argument so that additional data can be added without breaking binary compatibility with existing contract code.

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/verify.html index fe9cd0713b..744b53e2db 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-contract/verify.html @@ -7,8 +7,8 @@ com.r3corda.core.contracts / DummyContract / verify

verify

- -fun verify(tx: TransactionForVerification): Unit
+ +fun verify(tx: TransactionForContract): Unit
Overrides Contract.verify

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. Must throw an exception if theres a problem that should prevent state transition. Takes a single object diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/-init-.html new file mode 100644 index 0000000000..9d914540ad --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/-init-.html @@ -0,0 +1,15 @@ + + +DummyState.<init> - + + + +com.r3corda.core.contracts / DummyState / <init>
+
+

<init>

+DummyState(magicNumber: Int = 0)
+

Dummy state for use in testing. Not part of any real contract.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/contract.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/contract.html new file mode 100644 index 0000000000..c1b97983da --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/contract.html @@ -0,0 +1,43 @@ + + +DummyState.contract - + + + +com.r3corda.core.contracts / DummyState / contract
+
+

contract

+ +val contract: DummyContract
+Overrides ContractState.contract
+

An instance of the contract class that will verify this state.

+

Discussion

+

This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

+

Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

+

Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

+

This means that a smart contract in Corda does two things:

+
  1. Define the data structures that compose the ledger (the states)

    +
  2. Define the rules for updating those structures

    +

The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

+
  • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

    +
  • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

    +
  • Attachments (1, 2, 3) may all be used with this state.

    +

and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

+

Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

+

TODO: Implement the above description. See COR-226

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/index.html new file mode 100644 index 0000000000..77dc38aeb6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/index.html @@ -0,0 +1,70 @@ + + +DummyState - + + + +com.r3corda.core.contracts / DummyState
+
+

DummyState

+data class DummyState : ContractState
+

Dummy state for use in testing. Not part of any real contract.

+
+
+

Constructors

+ + + + + + + +
+<init> +DummyState(magicNumber: Int = 0)

Dummy state for use in testing. Not part of any real contract.

+
+

Properties

+ + + + + + + + + + + + + + + +
+contract +val contract: DummyContract

An instance of the contract class that will verify this state.

+
+magicNumber +val magicNumber: Int
+participants +val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+

Extension Functions

+ + + + + + + + + + + +
+hash +fun ContractState.hash(): SecureHash

Returns the SHA-256 hash of the serialised contents of this state (not cached)

+
+with notary +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/magic-number.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/magic-number.html new file mode 100644 index 0000000000..024318b7e0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/magic-number.html @@ -0,0 +1,15 @@ + + +DummyState.magicNumber - + + + +com.r3corda.core.contracts / DummyState / magicNumber
+
+

magicNumber

+ +val magicNumber: Int
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/participants.html b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/participants.html new file mode 100644 index 0000000000..4241d3c946 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-dummy-state/participants.html @@ -0,0 +1,34 @@ + + +DummyState.participants - + + + +com.r3corda.core.contracts / DummyState / participants
+
+

participants

+ +val participants: List<PublicKey>
+Overrides ContractState.participants
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+
+
+

Getter
+

A participant is any party that is able to consume this state in a valid transaction.

+

The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

+

The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/generate-fix.html b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/generate-fix.html index 8ab06e0b17..d2a9c9ceab 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/generate-fix.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/generate-fix.html @@ -7,8 +7,8 @@ com.r3corda.core.contracts / FixableDealState / generateFix

generateFix

- -abstract fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix): Unit
+ +abstract fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix): Unit

Generate a fixing command for this deal and fix

TODO: This would also likely move to methods on the Contract once the changes to reference the Contract from the ContractState are in

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/index.html index 27dc826099..2ad6ee1f9d 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/index.html @@ -37,7 +37,7 @@ generateFix -abstract fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix): Unit

Generate a fixing command for this deal and fix

+abstract fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix): Unit

Generate a fixing command for this deal and fix

@@ -56,7 +56,7 @@ generateAgreement -abstract fun generateAgreement(): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general +abstract fun generateAgreement(notary: Party): TransactionBuilder

Generate a partial transaction representing an agreement (command) to this deal, allowing a general deal/agreement protocol to generate the necessary transaction for potential implementations

@@ -80,9 +80,9 @@ deal/agreement protocol to generate the necessary transaction for potential impl -label +with notary -infix fun ContractState.label(label: String): LabeledOutput +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState> @@ -93,7 +93,7 @@ deal/agreement protocol to generate the necessary transaction for potential impl State -data class State : FixableDealState

The state class contains the 4 major data classes

+data class State : FixableDealState, SchedulableState

The state class contains the 4 major data classes

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/next-fixing-of.html b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/next-fixing-of.html index d0591aaaf3..0b27ea8c66 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/next-fixing-of.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-fixable-deal-state/next-fixing-of.html @@ -10,9 +10,6 @@ abstract fun nextFixingOf(): FixOf?

When is the next fixing and what is the fixing for?

-

TODO: In future we would use this to register for an event to trigger a/the fixing protocol

-
-


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issuance-definition.html b/docs/build/html/api/com.r3corda.core.contracts/-issuance-definition.html index a595ee54d2..0d857c9478 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-issuance-definition.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-issuance-definition.html @@ -12,18 +12,5 @@ from which the state object is initialised.



-

Inheritors

- - - - - - - -
-AssetIssuanceDefinition -interface AssetIssuanceDefinition<T> : IssuanceDefinition

Subset of cash-like contract state, containing the issuance definition. If these definitions match for two -contracts states, those states can be aggregated.

-
diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issue-command/index.html b/docs/build/html/api/com.r3corda.core.contracts/-issue-command/index.html new file mode 100644 index 0000000000..2d8504eb6e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issue-command/index.html @@ -0,0 +1,39 @@ + + +IssueCommand - + + + +com.r3corda.core.contracts / IssueCommand
+
+

IssueCommand

+interface IssueCommand : CommandData
+

A common issue command, to enforce that issue commands have a nonce value.

+
+
+

Properties

+ + + + + + + +
+nonce +abstract val nonce: Long
+

Inheritors

+ + + + + + + +
+Issue +interface Issue : IssueCommand, Commands

Allows new asset states to be issued into existence: the nonce ("number used once") ensures the transaction +has a unique ID even when there are no inputs.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issue-command/nonce.html b/docs/build/html/api/com.r3corda.core.contracts/-issue-command/nonce.html new file mode 100644 index 0000000000..cce229d7fe --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issue-command/nonce.html @@ -0,0 +1,15 @@ + + +IssueCommand.nonce - + + + +com.r3corda.core.contracts / IssueCommand / nonce
+
+

nonce

+ +abstract val nonce: Long
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issued/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-issued/-init-.html new file mode 100644 index 0000000000..1d10e49dff --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issued/-init-.html @@ -0,0 +1,19 @@ + + +Issued.<init> - + + + +com.r3corda.core.contracts / Issued / <init>
+
+

<init>

+Issued(issuer: PartyAndReference, product: P)
+

Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else thats +quantifiable with integer quantities.

+

Parameters

+ +P - the type of product underlying the definition, for example Currency.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issued/index.html b/docs/build/html/api/com.r3corda.core.contracts/-issued/index.html new file mode 100644 index 0000000000..63db904130 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issued/index.html @@ -0,0 +1,61 @@ + + +Issued - + + + +com.r3corda.core.contracts / Issued
+
+

Issued

+data class Issued<P>
+

Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else thats +quantifiable with integer quantities.

+

Parameters

+ +P - the type of product underlying the definition, for example Currency.
+
+
+

Constructors

+ + + + + + + +
+<init> +Issued(issuer: PartyAndReference, product: P)

Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else thats +quantifiable with integer quantities.

+
+

Properties

+ + + + + + + + + + + +
+issuer +val issuer: PartyAndReference
+product +val product: P
+

Extension Properties

+ + + + + + + +
+OBLIGATION_DEF +val Issued<Currency>.OBLIGATION_DEF: StateTemplate<Currency>

Allows you to write 100.DOLLARS.CASH

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issued/issuer.html b/docs/build/html/api/com.r3corda.core.contracts/-issued/issuer.html new file mode 100644 index 0000000000..c09a42e04d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issued/issuer.html @@ -0,0 +1,15 @@ + + +Issued.issuer - + + + +com.r3corda.core.contracts / Issued / issuer
+
+

issuer

+ +val issuer: PartyAndReference
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-issued/product.html b/docs/build/html/api/com.r3corda.core.contracts/-issued/product.html new file mode 100644 index 0000000000..3af736aebe --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-issued/product.html @@ -0,0 +1,15 @@ + + +Issued.product - + + + +com.r3corda.core.contracts / Issued / product
+
+

product

+ +val product: P
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-c-h-f.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-c-h-f.html new file mode 100644 index 0000000000..3b0247952d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-c-h-f.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.CHF - + + + +com.r3corda.core.contracts / JavaTestHelpers / CHF
+
+

CHF

+ +val CHF: Currency
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-d-o-l-l-a-r-s.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-d-o-l-l-a-r-s.html new file mode 100644 index 0000000000..3a554556b6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-d-o-l-l-a-r-s.html @@ -0,0 +1,17 @@ + + +JavaTestHelpers.DOLLARS - + + + +com.r3corda.core.contracts / JavaTestHelpers / DOLLARS
+
+

DOLLARS

+ +fun DOLLARS(amount: Int): Amount<Currency>
+ +fun DOLLARS(amount: Double): Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-g-b-p.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-g-b-p.html new file mode 100644 index 0000000000..c58f8386f0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-g-b-p.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.GBP - + + + +com.r3corda.core.contracts / JavaTestHelpers / GBP
+
+

GBP

+ +val GBP: Currency
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-p-o-u-n-d-s.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-p-o-u-n-d-s.html new file mode 100644 index 0000000000..de743f0344 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-p-o-u-n-d-s.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.POUNDS - + + + +com.r3corda.core.contracts / JavaTestHelpers / POUNDS
+
+

POUNDS

+ +fun POUNDS(amount: Int): Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-s-w-i-s-s_-f-r-a-n-c-s.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-s-w-i-s-s_-f-r-a-n-c-s.html new file mode 100644 index 0000000000..f7386b8085 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-s-w-i-s-s_-f-r-a-n-c-s.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.SWISS_FRANCS - + + + +com.r3corda.core.contracts / JavaTestHelpers / SWISS_FRANCS
+
+

SWISS_FRANCS

+ +fun SWISS_FRANCS(amount: Int): Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-u-s-d.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-u-s-d.html new file mode 100644 index 0000000000..de201ece77 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/-u-s-d.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.USD - + + + +com.r3corda.core.contracts / JavaTestHelpers / USD
+
+

USD

+ +val USD: Currency
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/index.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/index.html new file mode 100644 index 0000000000..c17d7473a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/index.html @@ -0,0 +1,68 @@ + + +JavaTestHelpers - + + + +com.r3corda.core.contracts / JavaTestHelpers
+
+

JavaTestHelpers

+object JavaTestHelpers
+
+
+

Properties

+ + + + + + + + + + + + + + + +
+CHF +val CHF: Currency
+GBP +val GBP: Currency
+USD +val USD: Currency
+

Functions

+ + + + + + + + + + + + + + + + + + + +
+DOLLARS +fun DOLLARS(amount: Int): Amount<Currency>
+fun DOLLARS(amount: Double): Amount<Currency>
+POUNDS +fun POUNDS(amount: Int): Amount<Currency>
+SWISS_FRANCS +fun SWISS_FRANCS(amount: Int): Amount<Currency>
+issuedBy +fun issuedBy(currency: Currency, deposit: PartyAndReference): Issued<Currency>
+fun issuedBy(amount: Amount<Currency>, deposit: PartyAndReference): Amount<Issued<Currency>>
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/issued-by.html b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/issued-by.html new file mode 100644 index 0000000000..1293a9d956 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-java-test-helpers/issued-by.html @@ -0,0 +1,17 @@ + + +JavaTestHelpers.issuedBy - + + + +com.r3corda.core.contracts / JavaTestHelpers / issuedBy
+
+

issuedBy

+ +fun issuedBy(currency: Currency, deposit: PartyAndReference): Issued<Currency>
+ +fun issuedBy(amount: Amount<Currency>, deposit: PartyAndReference): Amount<Issued<Currency>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/-init-.html index e04a3a7d77..b43c213d2a 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / LedgerTransaction / <init>

<init>

-LedgerTransaction(inputs: List<StateRef>, attachments: List<Attachment>, outputs: List<ContractState>, commands: List<AuthenticatedObject<CommandData>>, id: SecureHash)
+LedgerTransaction(inputs: List<StateRef>, outputs: List<TransactionState<*>>, commands: List<AuthenticatedObject<CommandData>>, attachments: List<Attachment>, id: SecureHash, signers: List<PublicKey>, type: TransactionType)

A LedgerTransaction wraps the data needed to calculate one or more successor states from a set of input states. It is the first step after extraction from a WireTransaction. The signatures at this point have been lined up with the commands from the wire, and verified/looked up.

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/index.html b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/index.html index 871775a400..66319c54e7 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/index.html @@ -23,7 +23,7 @@ with the commands from the wire, and verified/looked up.

<init> -LedgerTransaction(inputs: List<StateRef>, attachments: List<Attachment>, outputs: List<ContractState>, commands: List<AuthenticatedObject<CommandData>>, id: SecureHash)

A LedgerTransaction wraps the data needed to calculate one or more successor states from a set of input states. +LedgerTransaction(inputs: List<StateRef>, outputs: List<TransactionState<*>>, commands: List<AuthenticatedObject<CommandData>>, attachments: List<Attachment>, id: SecureHash, signers: List<PublicKey>, type: TransactionType)

A LedgerTransaction wraps the data needed to calculate one or more successor states from a set of input states. It is the first step after extraction from a WireTransaction. The signatures at this point have been lined up with the commands from the wire, and verified/looked up.

@@ -65,9 +65,21 @@ with the commands from the wire, and verified/looked up.

outputs -val outputs: List<ContractState>

The states that will be generated by the execution of this transaction.

+val outputs: List<TransactionState<*>>

The states that will be generated by the execution of this transaction.

+ + +signers + +val signers: List<PublicKey> + + + +type + +val type: TransactionType +

Functions

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/outputs.html index 01a46ad49e..8b5138d562 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/outputs.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/outputs.html @@ -8,7 +8,7 @@

outputs

-val outputs: List<ContractState>
+val outputs: List<TransactionState<*>>

The states that will be generated by the execution of this transaction.



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/signers.html b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/signers.html new file mode 100644 index 0000000000..a642a4a5b2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/signers.html @@ -0,0 +1,15 @@ + + +LedgerTransaction.signers - + + + +com.r3corda.core.contracts / LedgerTransaction / signers
+
+

signers

+ +val signers: List<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/type.html b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/type.html new file mode 100644 index 0000000000..c2bc0b4cea --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-ledger-transaction/type.html @@ -0,0 +1,15 @@ + + +LedgerTransaction.type - + + + +com.r3corda.core.contracts / LedgerTransaction / type
+
+

type

+ +val type: TransactionType
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-linear-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/index.html index f09912513b..abc8dfb712 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-linear-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/index.html @@ -33,14 +33,14 @@ contract -abstract val contract: Contract

Contract by which the state belongs

+abstract val contract: Contract

An instance of the contract class that will verify this state.

-notary +participants -abstract val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+abstract val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

@@ -69,9 +69,9 @@ -label +with notary -infix fun ContractState.label(label: String): LabeledOutput +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState> @@ -86,6 +86,12 @@ implementation of general protocols that manipulate many agreement types.

+ + +DummyLinearState + +class DummyLinearState : LinearState + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-move-command/contract-hash.html b/docs/build/html/api/com.r3corda.core.contracts/-move-command/contract-hash.html new file mode 100644 index 0000000000..ea6950577f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-move-command/contract-hash.html @@ -0,0 +1,17 @@ + + +MoveCommand.contractHash - + + + +com.r3corda.core.contracts / MoveCommand / contractHash
+
+

contractHash

+ +abstract val contractHash: SecureHash?
+

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-move-command/index.html b/docs/build/html/api/com.r3corda.core.contracts/-move-command/index.html new file mode 100644 index 0000000000..ece58372ea --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-move-command/index.html @@ -0,0 +1,46 @@ + + +MoveCommand - + + + +com.r3corda.core.contracts / MoveCommand
+
+

MoveCommand

+interface MoveCommand : CommandData
+

A common move command for contracts which can change owner.

+
+
+

Properties

+ + + + + + + +
+contractHash +abstract val contractHash: SecureHash?

Contract code the moved state(s) are for the attention of, for example to indicate that the states are moved in +order to settle an obligation contracts state object(s).

+
+

Inheritors

+ + + + + + + + + + + +
+Move +interface Move : MoveCommand, Commands
+Move +data class Move<P> : Commands, IssuanceCommands<P>, MoveCommand

A command stating that a debt has been moved, optionally to fulfil another contract.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-net-type/-c-l-o-s-e_-o-u-t.html b/docs/build/html/api/com.r3corda.core.contracts/-net-type/-c-l-o-s-e_-o-u-t.html new file mode 100644 index 0000000000..b1c11c7347 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-net-type/-c-l-o-s-e_-o-u-t.html @@ -0,0 +1,20 @@ + + +NetType.CLOSE_OUT - + + + +com.r3corda.core.contracts / NetType / CLOSE_OUT
+
+

CLOSE_OUT

+CLOSE_OUT
+

Close-out netting applies where one party is bankrupt or otherwise defaults (exact terms are contract specific), +and allows their counterparty to net obligations without requiring approval from all parties. For example, if +Bank A owes Bank B £1m, and Bank B owes Bank A £1m, in the case of Bank B defaulting this would enable Bank A +to net out the two obligations to zero, rather than being legally obliged to pay £1m without any realistic +expectation of the debt to them being paid. Realistically this is limited to bilateral netting, to simplify +determining which party must sign the netting transaction.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-net-type/-p-a-y-m-e-n-t.html b/docs/build/html/api/com.r3corda.core.contracts/-net-type/-p-a-y-m-e-n-t.html new file mode 100644 index 0000000000..8d18b3c036 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-net-type/-p-a-y-m-e-n-t.html @@ -0,0 +1,16 @@ + + +NetType.PAYMENT - + + + +com.r3corda.core.contracts / NetType / PAYMENT
+
+

PAYMENT

+PAYMENT
+

"Payment" is used to refer to conventional netting, where all parties must confirm the netting transaction. This +can be a multilateral netting transaction, and may be created by a central clearing service.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-net-type/index.html b/docs/build/html/api/com.r3corda.core.contracts/-net-type/index.html new file mode 100644 index 0000000000..54d9adf316 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-net-type/index.html @@ -0,0 +1,41 @@ + + +NetType - + + + +com.r3corda.core.contracts / NetType
+
+

NetType

+enum class NetType
+

Enum for the types of netting that can be applied to state objects. Exact behaviour +for each type of netting is left to the contract to determine.

+
+
+

Enum Values

+ + + + + + + + + + + +
+CLOSE_OUT +

Close-out netting applies where one party is bankrupt or otherwise defaults (exact terms are contract specific), +and allows their counterparty to net obligations without requiring approval from all parties. For example, if +Bank A owes Bank B £1m, and Bank B owes Bank A £1m, in the case of Bank B defaulting this would enable Bank A +to net out the two obligations to zero, rather than being legally obliged to pay £1m without any realistic +expectation of the debt to them being paid. Realistically this is limited to bilateral netting, to simplify +determining which party must sign the netting transaction.

+
+PAYMENT +

"Payment" is used to refer to conventional netting, where all parties must confirm the netting transaction. This +can be a multilateral netting transaction, and may be created by a central clearing service.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-ownable-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-ownable-state/index.html index f55cc49182..ba3ea8edf3 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-ownable-state/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-ownable-state/index.html @@ -30,14 +30,14 @@ contract -abstract val contract: Contract

Contract by which the state belongs

+abstract val contract: Contract

An instance of the contract class that will verify this state.

-notary +participants -abstract val notary: Party

Identity of the notary that ensures this state is not used as an input to a transaction more than once

+abstract val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

@@ -66,9 +66,9 @@ -label +with notary -infix fun ContractState.label(label: String): LabeledOutput +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState> @@ -77,13 +77,19 @@ -FungibleAssetState +FungibleAssetState -interface FungibleAssetState<T, I : AssetIssuanceDefinition<T>> : OwnableState

Common elements of cash contract states.

+interface FungibleAssetState<T, I> : OwnableState

Common elements of cash contract states.

+SingleOwnerState + +data class SingleOwnerState : OwnableState, State + + + State data class State : OwnableState diff --git a/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/index.html new file mode 100644 index 0000000000..6447cb547f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/index.html @@ -0,0 +1,77 @@ + + +SchedulableState - + + + +com.r3corda.core.contracts / SchedulableState
+
+

SchedulableState

+interface SchedulableState : ContractState
+
+
+

Inherited Properties

+ + + + + + + + + + + +
+contract +abstract val contract: Contract

An instance of the contract class that will verify this state.

+
+participants +abstract val participants: List<PublicKey>

A participant is any party that is able to consume this state in a valid transaction.

+
+

Functions

+ + + + + + + +
+nextScheduledActivity +abstract fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity?

Indicate whether there is some activity to be performed at some future point in time with respect to this +ContractState, what that activity is and at what point in time it should be initiated. +This can be used to implement deadlines for payment or processing of financial instruments according to a schedule.

+
+

Extension Functions

+ + + + + + + + + + + +
+hash +fun ContractState.hash(): SecureHash

Returns the SHA-256 hash of the serialised contents of this state (not cached)

+
+with notary +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
+

Inheritors

+ + + + + + + +
+State +data class State : FixableDealState, SchedulableState

The state class contains the 4 major data classes

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/next-scheduled-activity.html b/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/next-scheduled-activity.html new file mode 100644 index 0000000000..7afd1dc545 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-schedulable-state/next-scheduled-activity.html @@ -0,0 +1,23 @@ + + +SchedulableState.nextScheduledActivity - + + + +com.r3corda.core.contracts / SchedulableState / nextScheduledActivity
+
+

nextScheduledActivity

+ +abstract fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity?
+

Indicate whether there is some activity to be performed at some future point in time with respect to this +ContractState, what that activity is and at what point in time it should be initiated. +This can be used to implement deadlines for payment or processing of financial instruments according to a schedule.

+

The state has no reference to its own StateRef, so supply that for use as input to any ProtocolLogic constructed.

+
+
+

Return
+null if there is no activity to schedule

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/-init-.html new file mode 100644 index 0000000000..604f267215 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/-init-.html @@ -0,0 +1,23 @@ + + +ScheduledActivity.<init> - + + + +com.r3corda.core.contracts / ScheduledActivity / <init>
+
+

<init>

+ScheduledActivity(logicRef: ProtocolLogicRef, scheduledAt: Instant)
+

This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

+

Note the use of ProtocolLogicRef to represent a safe way to transport a ProtocolLogic out of the contract sandbox.

+

Currently we support only protocol based activities as we expect there to be a transaction generated off the back of +the activity, otherwise we have to start tracking secondary state on the platform of which scheduled activities +for a particular ContractState have been processed/fired etc. If the activity is not "on ledger" then the +scheduled activity shouldnt be either.

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/index.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/index.html new file mode 100644 index 0000000000..e7d1e45b83 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/index.html @@ -0,0 +1,53 @@ + + +ScheduledActivity - + + + +com.r3corda.core.contracts / ScheduledActivity
+
+

ScheduledActivity

+data class ScheduledActivity : Scheduled
+

This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

+

Note the use of ProtocolLogicRef to represent a safe way to transport a ProtocolLogic out of the contract sandbox.

+

Currently we support only protocol based activities as we expect there to be a transaction generated off the back of +the activity, otherwise we have to start tracking secondary state on the platform of which scheduled activities +for a particular ContractState have been processed/fired etc. If the activity is not "on ledger" then the +scheduled activity shouldnt be either.

+
+
+
+
+

Constructors

+ + + + + + + +
+<init> +ScheduledActivity(logicRef: ProtocolLogicRef, scheduledAt: Instant)

This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

+
+

Properties

+ + + + + + + + + + + +
+logicRef +val logicRef: ProtocolLogicRef
+scheduledAt +val scheduledAt: Instant
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/logic-ref.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/logic-ref.html new file mode 100644 index 0000000000..32742e0116 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/logic-ref.html @@ -0,0 +1,15 @@ + + +ScheduledActivity.logicRef - + + + +com.r3corda.core.contracts / ScheduledActivity / logicRef
+
+

logicRef

+ +val logicRef: ProtocolLogicRef
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/scheduled-at.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/scheduled-at.html new file mode 100644 index 0000000000..be021fba3f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-activity/scheduled-at.html @@ -0,0 +1,16 @@ + + +ScheduledActivity.scheduledAt - + + + +com.r3corda.core.contracts / ScheduledActivity / scheduledAt
+
+

scheduledAt

+ +val scheduledAt: Instant
+Overrides Scheduled.scheduledAt
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/-init-.html new file mode 100644 index 0000000000..59f1ad274c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/-init-.html @@ -0,0 +1,20 @@ + + +ScheduledStateRef.<init> - + + + +com.r3corda.core.contracts / ScheduledStateRef / <init>
+
+

<init>

+ScheduledStateRef(ref: StateRef, scheduledAt: Instant)
+

Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

+

This is effectively the input to a scheduler, which wakes up at that point in time and asks the contract state what +lifecycle processing needs to take place. e.g. a fixing or a late payment etc.

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/index.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/index.html new file mode 100644 index 0000000000..4a4df2e7c2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/index.html @@ -0,0 +1,50 @@ + + +ScheduledStateRef - + + + +com.r3corda.core.contracts / ScheduledStateRef
+
+

ScheduledStateRef

+data class ScheduledStateRef : Scheduled
+

Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

+

This is effectively the input to a scheduler, which wakes up at that point in time and asks the contract state what +lifecycle processing needs to take place. e.g. a fixing or a late payment etc.

+
+
+
+
+

Constructors

+ + + + + + + +
+<init> +ScheduledStateRef(ref: StateRef, scheduledAt: Instant)

Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

+
+

Properties

+ + + + + + + + + + + +
+ref +val ref: StateRef
+scheduledAt +val scheduledAt: Instant
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/ref.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/ref.html new file mode 100644 index 0000000000..5f2c7932f3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/ref.html @@ -0,0 +1,15 @@ + + +ScheduledStateRef.ref - + + + +com.r3corda.core.contracts / ScheduledStateRef / ref
+
+

ref

+ +val ref: StateRef
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/scheduled-at.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/scheduled-at.html new file mode 100644 index 0000000000..8680d93656 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled-state-ref/scheduled-at.html @@ -0,0 +1,16 @@ + + +ScheduledStateRef.scheduledAt - + + + +com.r3corda.core.contracts / ScheduledStateRef / scheduledAt
+
+

scheduledAt

+ +val scheduledAt: Instant
+Overrides Scheduled.scheduledAt
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled/index.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled/index.html new file mode 100644 index 0000000000..66a480fa8d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled/index.html @@ -0,0 +1,47 @@ + + +Scheduled - + + + +com.r3corda.core.contracts / Scheduled
+
+

Scheduled

+interface Scheduled
+

Something which is scheduled to happen at a point in time

+
+
+

Properties

+ + + + + + + +
+scheduledAt +abstract val scheduledAt: Instant
+

Inheritors

+ + + + + + + + + + + +
+ScheduledActivity +data class ScheduledActivity : Scheduled

This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

+
+ScheduledStateRef +data class ScheduledStateRef : Scheduled

Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-scheduled/scheduled-at.html b/docs/build/html/api/com.r3corda.core.contracts/-scheduled/scheduled-at.html new file mode 100644 index 0000000000..cbe74a1e93 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-scheduled/scheduled-at.html @@ -0,0 +1,15 @@ + + +Scheduled.scheduledAt - + + + +com.r3corda.core.contracts / Scheduled / scheduledAt
+
+

scheduledAt

+ +abstract val scheduledAt: Instant
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/get-missing-signatures.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/get-missing-signatures.html index 90f1758b92..0c043b0153 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/get-missing-signatures.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/get-missing-signatures.html @@ -9,8 +9,7 @@

getMissingSignatures

fun getMissingSignatures(): Set<PublicKey>
-

Returns the set of missing signatures - a signature must be present for every command pub key -and the Notary (if it is specified)

+

Returns the set of missing signatures - a signature must be present for each signer public key



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/index.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/index.html index dfccafff93..4d11ec7b27 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/index.html @@ -61,8 +61,7 @@ getMissingSignatures -fun getMissingSignatures(): Set<PublicKey>

Returns the set of missing signatures - a signature must be present for every command pub key -and the Notary (if it is specified)

+fun getMissingSignatures(): Set<PublicKey>

Returns the set of missing signatures - a signature must be present for each signer public key

@@ -70,14 +69,14 @@ and the Notary (if it is specified)

plus operator fun plus(sig: WithKey): SignedTransaction

Alias for withAdditionalSignature to let you use Kotlin operator overloading.

- +operator fun plus(sigList: Collection<WithKey>): SignedTransaction verify fun verify(throwIfSignaturesAreMissing: Boolean = true): Set<PublicKey>

Verify the signatures, deserialise the wire transaction and then check that the set of signatures found contains -the set of pubkeys in the commands. If any signatures are missing, either throws an exception (by default) or +the set of pubkeys in the signers list. If any signatures are missing, either throws an exception (by default) or returns the list of keys that have missing signatures, depending on the parameter.

@@ -97,6 +96,12 @@ checking a partially signed transaction being prepared by multiple co-operating fun withAdditionalSignature(sig: WithKey): SignedTransaction

Returns the same transaction but with an additional (unchecked) signature

+ + +withAdditionalSignatures + +fun withAdditionalSignatures(sigList: Iterable<WithKey>): SignedTransaction +

Extension Functions

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/plus.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/plus.html index c450cf561e..d8e3ac543a 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/plus.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/plus.html @@ -12,5 +12,9 @@

Alias for withAdditionalSignature to let you use Kotlin operator overloading.



+ +operator fun plus(sigList: Collection<WithKey>): SignedTransaction
+
+
diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/tx.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/tx.html index 4b97256695..b2e2811d52 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/tx.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/tx.html @@ -10,9 +10,9 @@ val tx: WireTransaction

Lazily calculated access to the deserialised/hashed transaction data.

-Getter
+

Getter

Lazily calculated access to the deserialised/hashed transaction data.

-
+



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/verify.html index c7caf39669..a2e9064ac6 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/verify.html @@ -10,7 +10,7 @@ fun verify(throwIfSignaturesAreMissing: Boolean = true): Set<PublicKey>

Verify the signatures, deserialise the wire transaction and then check that the set of signatures found contains -the set of pubkeys in the commands. If any signatures are missing, either throws an exception (by default) or +the set of pubkeys in the signers list. If any signatures are missing, either throws an exception (by default) or returns the list of keys that have missing signatures, depending on the parameter.

Exceptions

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/with-additional-signatures.html b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/with-additional-signatures.html new file mode 100644 index 0000000000..32618083f0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-signed-transaction/with-additional-signatures.html @@ -0,0 +1,15 @@ + + +SignedTransaction.withAdditionalSignatures - + + + +com.r3corda.core.contracts / SignedTransaction / withAdditionalSignatures
+
+

withAdditionalSignatures

+ +fun withAdditionalSignatures(sigList: Iterable<WithKey>): SignedTransaction
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/-init-.html index 3e25b05185..f247f2f7c4 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / StateAndRef / <init>

<init>

-StateAndRef(state: T, ref: StateRef)
+StateAndRef(state: TransactionState<T>, ref: StateRef)

A StateAndRef is simply a (state, ref) pair. For instance, a wallet (which holds available assets) contains these.



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/index.html b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/index.html index ef748018a2..e02e74e348 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/index.html @@ -18,7 +18,7 @@ <init> -StateAndRef(state: T, ref: StateRef)

A StateAndRef is simply a (state, ref) pair. For instance, a wallet (which holds available assets) contains these.

+StateAndRef(state: TransactionState<T>, ref: StateRef)

A StateAndRef is simply a (state, ref) pair. For instance, a wallet (which holds available assets) contains these.

@@ -36,7 +36,7 @@ state -val state: T +val state: TransactionState<T> diff --git a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/state.html b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/state.html index 3d6a1637d9..1518f2e0b3 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/state.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-state-and-ref/state.html @@ -8,7 +8,7 @@

state

-val state: T
+val state: TransactionState<T>


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/-init-.html index 7ef194a8f8..1e4803e179 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/-init-.html @@ -7,11 +7,19 @@ com.r3corda.core.contracts / TransactionBuilder / <init>

<init>

-TransactionBuilder(inputs: MutableList<StateRef> = arrayListOf(), attachments: MutableList<SecureHash> = arrayListOf(), outputs: MutableList<ContractState> = arrayListOf(), commands: MutableList<Command> = arrayListOf())
+TransactionBuilder(type: TransactionType = TransactionType.General(), notary: Party? = null)

A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is -intended to be passed around contracts that may edit it by adding new states/commands or modifying the existing set. -Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from -multiple parties.

+intended to be passed around contracts that may edit it by adding new states/commands. Then once the states +and commands are right, this class can be used as a holding bucket to gather signatures from multiple parties.

+

The builder can be customised for specific transaction types, e.g. where additional processing is needed +before adding a state/command.

+
+
+

Parameters

+ +notary - The default notary that will be used for outputs that dont have a notary specified. When this is set, +an output state can be added by just passing in a ContractState – a TransactionState with the +default notary will be generated automatically.


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-input-state.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-input-state.html index 7e4d4e16de..7196d6a1d4 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-input-state.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-input-state.html @@ -7,8 +7,8 @@ com.r3corda.core.contracts / TransactionBuilder / addInputState

addInputState

- -fun addInputState(ref: StateRef): Unit
+ +open fun addInputState(stateAndRef: StateAndRef<*>): Unit


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-output-state.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-output-state.html index 36e9cd001b..14e1ef2f1c 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-output-state.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/add-output-state.html @@ -7,8 +7,15 @@ com.r3corda.core.contracts / TransactionBuilder / addOutputState

addOutputState

+ +fun addOutputState(state: TransactionState<*>): Unit
+ +fun addOutputState(state: ContractState, notary: Party): Unit
+
+
fun addOutputState(state: ContractState): Unit
+

A default notary must be specified during builder construction to use this method



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/attachments.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/attachments.html index 62c96d769f..03f7b1559e 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/attachments.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/attachments.html @@ -7,6 +7,8 @@ com.r3corda.core.contracts / TransactionBuilder / attachments

attachments

+ +protected val attachments: MutableList<SecureHash>
fun attachments(): List<SecureHash>

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/commands.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/commands.html index 436ed87251..eeed2f65d1 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/commands.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/commands.html @@ -7,6 +7,8 @@ com.r3corda.core.contracts / TransactionBuilder / commands

commands

+ +protected val commands: MutableList<Command>
fun commands(): List<Command>

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/current-sigs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/current-sigs.html new file mode 100644 index 0000000000..fe2ffdc034 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/current-sigs.html @@ -0,0 +1,16 @@ + + +TransactionBuilder.currentSigs - + + + +com.r3corda.core.contracts / TransactionBuilder / currentSigs
+
+

currentSigs

+ +protected val currentSigs: <ERROR CLASS>
+

The signatures that have been collected so far - might be incomplete

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/index.html index 4039741152..7b5f97a21f 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/index.html @@ -7,11 +7,19 @@ com.r3corda.core.contracts / TransactionBuilder

TransactionBuilder

-class TransactionBuilder
+abstract class TransactionBuilder

A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is -intended to be passed around contracts that may edit it by adding new states/commands or modifying the existing set. -Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from -multiple parties.

+intended to be passed around contracts that may edit it by adding new states/commands. Then once the states +and commands are right, this class can be used as a holding bucket to gather signatures from multiple parties.

+

The builder can be customised for specific transaction types, e.g. where additional processing is needed +before adding a state/command.

+
+
+

Parameters

+ +notary - The default notary that will be used for outputs that dont have a notary specified. When this is set, +an output state can be added by just passing in a ContractState – a TransactionState with the +default notary will be generated automatically.


Constructors

@@ -21,10 +29,9 @@ multiple parties.

<init> -TransactionBuilder(inputs: MutableList<StateRef> = arrayListOf(), attachments: MutableList<SecureHash> = arrayListOf(), outputs: MutableList<ContractState> = arrayListOf(), commands: MutableList<Command> = arrayListOf())

A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is -intended to be passed around contracts that may edit it by adding new states/commands or modifying the existing set. -Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from -multiple parties.

+TransactionBuilder(type: TransactionType = TransactionType.General(), notary: Party? = null)

A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is +intended to be passed around contracts that may edit it by adding new states/commands. Then once the states +and commands are right, this class can be used as a holding bucket to gather signatures from multiple parties.

@@ -34,10 +41,59 @@ multiple parties.

+attachments + +val attachments: MutableList<SecureHash> + + + +commands + +val commands: MutableList<Command> + + + +currentSigs + +val currentSigs: <ERROR CLASS>

The signatures that have been collected so far - might be incomplete

+ + + + +inputs + +val inputs: MutableList<StateRef> + + + +notary + +val notary: Party? + + + +outputs + +val outputs: MutableList<TransactionState<ContractState>> + + + +signers + +val signers: MutableSet<PublicKey> + + + time val time: TimestampCommand? + + +type + +val type: TransactionType +

Functions

@@ -61,13 +117,15 @@ multiple parties.

addInputState -fun addInputState(ref: StateRef): Unit +open fun addInputState(stateAndRef: StateAndRef<*>): Unit addOutputState -fun addOutputState(state: ContractState): Unit +fun addOutputState(state: TransactionState<*>): Unit
+fun addOutputState(state: ContractState, notary: Party): Unitfun addOutputState(state: ContractState): Unit

A default notary must be specified during builder construction to use this method

+ @@ -113,7 +171,7 @@ adds it.

outputStates -fun outputStates(): List<ContractState> +fun outputStates(): List<TransactionState<*>> @@ -151,5 +209,25 @@ The signature can be obtained using NotaryProtocol.

+

Inheritors

+ + + + + + + + + + + +
+Builder +class Builder : TransactionBuilder

Just uses the default TransactionBuilder with no special logic

+
+Builder +class Builder : TransactionBuilder

A transaction builder that automatically sets the transaction type to NotaryChange +and adds the list of participants to the signers set for every input state.

+
diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/inputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/inputs.html new file mode 100644 index 0000000000..0fe3c2ebc8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/inputs.html @@ -0,0 +1,15 @@ + + +TransactionBuilder.inputs - + + + +com.r3corda.core.contracts / TransactionBuilder / inputs
+
+

inputs

+ +protected val inputs: MutableList<StateRef>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/notary.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/notary.html new file mode 100644 index 0000000000..c1b9529273 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/notary.html @@ -0,0 +1,15 @@ + + +TransactionBuilder.notary - + + + +com.r3corda.core.contracts / TransactionBuilder / notary
+
+

notary

+ +protected val notary: Party?
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/output-states.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/output-states.html index 9eae76eb5f..927518ba49 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/output-states.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/output-states.html @@ -8,7 +8,7 @@

outputStates

-fun outputStates(): List<ContractState>
+fun outputStates(): List<TransactionState<*>>


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/outputs.html new file mode 100644 index 0000000000..7467bf59d1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/outputs.html @@ -0,0 +1,15 @@ + + +TransactionBuilder.outputs - + + + +com.r3corda.core.contracts / TransactionBuilder / outputs
+
+

outputs

+ +protected val outputs: MutableList<TransactionState<ContractState>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/signers.html new file mode 100644 index 0000000000..0829ae968c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/signers.html @@ -0,0 +1,15 @@ + + +TransactionBuilder.signers - + + + +com.r3corda.core.contracts / TransactionBuilder / signers
+
+

signers

+ +protected val signers: MutableSet<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/type.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/type.html new file mode 100644 index 0000000000..7665ef3de4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-builder/type.html @@ -0,0 +1,15 @@ + + +TransactionBuilder.type - + + + +com.r3corda.core.contracts / TransactionBuilder / type
+
+

type

+ +protected val type: TransactionType
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/-init-.html new file mode 100644 index 0000000000..96a3372ada --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/-init-.html @@ -0,0 +1,19 @@ + + +TransactionForContract.InOutGroup.<init> - + + + +com.r3corda.core.contracts / TransactionForContract / InOutGroup / <init>
+
+

<init>

+InOutGroup(inputs: List<T>, outputs: List<T>, groupingKey: K)
+

A set of related inputs and outputs that are connected by some common attributes. An InOutGroup is calculated +using groupStates and is useful for handling cases where a transaction may contain similar but unrelated +state evolutions, for example, a transaction that moves cash in two different currencies. The numbers must add +up on both sides of the transaction, but the values must be summed independently per currency. Grouping can +be used to simplify this logic.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/grouping-key.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/grouping-key.html new file mode 100644 index 0000000000..be2fab9b3b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/grouping-key.html @@ -0,0 +1,15 @@ + + +TransactionForContract.InOutGroup.groupingKey - + + + +com.r3corda.core.contracts / TransactionForContract / InOutGroup / groupingKey
+
+

groupingKey

+ +val groupingKey: K
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/index.html new file mode 100644 index 0000000000..8856eb2045 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/index.html @@ -0,0 +1,58 @@ + + +TransactionForContract.InOutGroup - + + + +com.r3corda.core.contracts / TransactionForContract / InOutGroup
+
+

InOutGroup

+data class InOutGroup<T : ContractState, K : Any>
+

A set of related inputs and outputs that are connected by some common attributes. An InOutGroup is calculated +using groupStates and is useful for handling cases where a transaction may contain similar but unrelated +state evolutions, for example, a transaction that moves cash in two different currencies. The numbers must add +up on both sides of the transaction, but the values must be summed independently per currency. Grouping can +be used to simplify this logic.

+
+
+

Constructors

+ + + + + + + +
+<init> +InOutGroup(inputs: List<T>, outputs: List<T>, groupingKey: K)

A set of related inputs and outputs that are connected by some common attributes. An InOutGroup is calculated +using groupStates and is useful for handling cases where a transaction may contain similar but unrelated +state evolutions, for example, a transaction that moves cash in two different currencies. The numbers must add +up on both sides of the transaction, but the values must be summed independently per currency. Grouping can +be used to simplify this logic.

+
+

Properties

+ + + + + + + + + + + + + + + +
+groupingKey +val groupingKey: K
+inputs +val inputs: List<T>
+outputs +val outputs: List<T>
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/inputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/inputs.html new file mode 100644 index 0000000000..18918db151 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/inputs.html @@ -0,0 +1,15 @@ + + +TransactionForContract.InOutGroup.inputs - + + + +com.r3corda.core.contracts / TransactionForContract / InOutGroup / inputs
+
+

inputs

+ +val inputs: List<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/outputs.html new file mode 100644 index 0000000000..4ba426e1f0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-in-out-group/outputs.html @@ -0,0 +1,15 @@ + + +TransactionForContract.InOutGroup.outputs - + + + +com.r3corda.core.contracts / TransactionForContract / InOutGroup / outputs
+
+

outputs

+ +val outputs: List<T>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-init-.html new file mode 100644 index 0000000000..fdaec02495 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/-init-.html @@ -0,0 +1,16 @@ + + +TransactionForContract.<init> - + + + +com.r3corda.core.contracts / TransactionForContract / <init>
+
+

<init>

+TransactionForContract(inputs: List<ContractState>, outputs: List<ContractState>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash)
+

A transaction to be passed as input to a contract verification function. Defines helper methods to +simplify verification logic in contracts.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/attachments.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/attachments.html new file mode 100644 index 0000000000..19a708f007 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/attachments.html @@ -0,0 +1,15 @@ + + +TransactionForContract.attachments - + + + +com.r3corda.core.contracts / TransactionForContract / attachments
+
+

attachments

+ +val attachments: List<Attachment>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/commands.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/commands.html new file mode 100644 index 0000000000..83eb9249d2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/commands.html @@ -0,0 +1,15 @@ + + +TransactionForContract.commands - + + + +com.r3corda.core.contracts / TransactionForContract / commands
+
+

commands

+ +val commands: List<AuthenticatedObject<CommandData>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/equals.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/equals.html new file mode 100644 index 0000000000..21e9265538 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/equals.html @@ -0,0 +1,15 @@ + + +TransactionForContract.equals - + + + +com.r3corda.core.contracts / TransactionForContract / equals
+
+

equals

+ +fun equals(other: Any?): Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by-name.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by-name.html new file mode 100644 index 0000000000..e733a73c40 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by-name.html @@ -0,0 +1,16 @@ + + +TransactionForContract.getTimestampByName - + + + +com.r3corda.core.contracts / TransactionForContract / getTimestampByName
+
+

getTimestampByName

+ +fun getTimestampByName(vararg authorityName: String): TimestampCommand?
+

Simply calls commands.getTimestampByName as a shortcut to make code completion more intuitive.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by.html new file mode 100644 index 0000000000..d37ebd5123 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/get-timestamp-by.html @@ -0,0 +1,16 @@ + + +TransactionForContract.getTimestampBy - + + + +com.r3corda.core.contracts / TransactionForContract / getTimestampBy
+
+

getTimestampBy

+ +fun getTimestampBy(timestampingAuthority: Party): TimestampCommand?
+

Simply calls commands.getTimestampBy as a shortcut to make code completion more intuitive.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-commands.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-commands.html new file mode 100644 index 0000000000..eee8109e42 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-commands.html @@ -0,0 +1,15 @@ + + +TransactionForContract.groupCommands - + + + +com.r3corda.core.contracts / TransactionForContract / groupCommands
+
+

groupCommands

+ +inline fun <reified T : CommandData, K> groupCommands(keySelector: (AuthenticatedObject<T>) -> K): Map<K, List<AuthenticatedObject<T>>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states-internal.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states-internal.html new file mode 100644 index 0000000000..b111392d3b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states-internal.html @@ -0,0 +1,17 @@ + + +TransactionForContract.groupStatesInternal - + + + +com.r3corda.core.contracts / TransactionForContract / groupStatesInternal
+
+

groupStatesInternal

+ +fun <T : ContractState, K : Any> groupStatesInternal(inGroups: Map<K, List<T>>, outGroups: Map<K, List<T>>): List<InOutGroup<T, K>>
+Deprecated: Do not use this directly: exposed as public only due to function inlining
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states.html new file mode 100644 index 0000000000..d1e842e179 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/group-states.html @@ -0,0 +1,33 @@ + + +TransactionForContract.groupStates - + + + +com.r3corda.core.contracts / TransactionForContract / groupStates
+
+

groupStates

+ +fun <T : ContractState, K : Any> groupStates(ofType: Class<T>, selector: (T) -> K): List<InOutGroup<T, K>>
+

Given a type and a function that returns a grouping key, associates inputs and outputs together so that they +can be processed as one. The grouping key is any arbitrary object that can act as a map key (so must implement +equals and hashCode).

+

The purpose of this function is to simplify the writing of verification logic for transactions that may contain +similar but unrelated state evolutions which need to be checked independently. Consider a transaction that +simultaneously moves both dollars and euros (e.g. is an atomic FX trade). There may be multiple dollar inputs and +multiple dollar outputs, depending on things like how fragmented the owners wallet is and whether various privacy +techniques are in use. The quantity of dollars on the output side must sum to the same as on the input side, to +ensure no money is being lost track of. This summation and checking must be repeated independently for each +currency. To solve this, you would use groupStates with a type of Cash.State and a selector that returns the +currency field: the resulting list can then be iterated over to perform the per-currency calculation.

+
+
+
+
+ +inline fun <reified T : ContractState, K : Any> groupStates(selector: (T) -> K): List<InOutGroup<T, K>>
+

See the documentation for the reflection-based version of groupStates

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/hash-code.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/hash-code.html new file mode 100644 index 0000000000..849bb50f94 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/hash-code.html @@ -0,0 +1,15 @@ + + +TransactionForContract.hashCode - + + + +com.r3corda.core.contracts / TransactionForContract / hashCode
+
+

hashCode

+ +fun hashCode(): Int
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/in-states.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/in-states.html new file mode 100644 index 0000000000..b50ec12d39 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/in-states.html @@ -0,0 +1,17 @@ + + +TransactionForContract.inStates - + + + +com.r3corda.core.contracts / TransactionForContract / inStates
+
+

inStates

+ +val inStates: List<ContractState>
+Deprecated: This property was renamed to inputs
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/index.html new file mode 100644 index 0000000000..f319ef5b32 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/index.html @@ -0,0 +1,145 @@ + + +TransactionForContract - + + + +com.r3corda.core.contracts / TransactionForContract
+
+

TransactionForContract

+data class TransactionForContract
+

A transaction to be passed as input to a contract verification function. Defines helper methods to +simplify verification logic in contracts.

+
+
+

Types

+ + + + + + + +
+InOutGroup +data class InOutGroup<T : ContractState, K : Any>

A set of related inputs and outputs that are connected by some common attributes. An InOutGroup is calculated +using groupStates and is useful for handling cases where a transaction may contain similar but unrelated +state evolutions, for example, a transaction that moves cash in two different currencies. The numbers must add +up on both sides of the transaction, but the values must be summed independently per currency. Grouping can +be used to simplify this logic.

+
+

Constructors

+ + + + + + + +
+<init> +TransactionForContract(inputs: List<ContractState>, outputs: List<ContractState>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash)

A transaction to be passed as input to a contract verification function. Defines helper methods to +simplify verification logic in contracts.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+attachments +val attachments: List<Attachment>
+commands +val commands: List<AuthenticatedObject<CommandData>>
+inStates +val inStates: List<ContractState>
+inputs +val inputs: List<ContractState>
+origHash +val origHash: SecureHash
+outStates +val outStates: List<ContractState>
+outputs +val outputs: List<ContractState>
+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+equals +fun equals(other: Any?): Boolean
+getTimestampBy +fun getTimestampBy(timestampingAuthority: Party): TimestampCommand?

Simply calls commands.getTimestampBy as a shortcut to make code completion more intuitive.

+
+getTimestampByName +fun getTimestampByName(vararg authorityName: String): TimestampCommand?

Simply calls commands.getTimestampByName as a shortcut to make code completion more intuitive.

+
+groupCommands +fun <T : CommandData, K> groupCommands(keySelector: (AuthenticatedObject<T>) -> K): Map<K, List<AuthenticatedObject<T>>>
+groupStates +fun <T : ContractState, K : Any> groupStates(ofType: Class<T>, selector: (T) -> K): List<InOutGroup<T, K>>

Given a type and a function that returns a grouping key, associates inputs and outputs together so that they +can be processed as one. The grouping key is any arbitrary object that can act as a map key (so must implement +equals and hashCode).

+fun <T : ContractState, K : Any> groupStates(selector: (T) -> K): List<InOutGroup<T, K>>

See the documentation for the reflection-based version of groupStates

+
+groupStatesInternal +fun <T : ContractState, K : Any> groupStatesInternal(inGroups: Map<K, List<T>>, outGroups: Map<K, List<T>>): List<InOutGroup<T, K>>
+hashCode +fun hashCode(): Int
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/inputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/inputs.html new file mode 100644 index 0000000000..e28849f290 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/inputs.html @@ -0,0 +1,15 @@ + + +TransactionForContract.inputs - + + + +com.r3corda.core.contracts / TransactionForContract / inputs
+
+

inputs

+ +val inputs: List<ContractState>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/orig-hash.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/orig-hash.html new file mode 100644 index 0000000000..357cc8b5da --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/orig-hash.html @@ -0,0 +1,15 @@ + + +TransactionForContract.origHash - + + + +com.r3corda.core.contracts / TransactionForContract / origHash
+
+

origHash

+ +val origHash: SecureHash
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/out-states.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/out-states.html new file mode 100644 index 0000000000..818d806c08 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/out-states.html @@ -0,0 +1,17 @@ + + +TransactionForContract.outStates - + + + +com.r3corda.core.contracts / TransactionForContract / outStates
+
+

outStates

+ +val outStates: List<ContractState>
+Deprecated: This property was renamed to outputs
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/outputs.html new file mode 100644 index 0000000000..3ff5ac87d8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-contract/outputs.html @@ -0,0 +1,15 @@ + + +TransactionForContract.outputs - + + + +com.r3corda.core.contracts / TransactionForContract / outputs
+
+

outputs

+ +val outputs: List<ContractState>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/-init-.html index ed7278a674..f89bdd0b79 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / TransactionForVerification / <init>

<init>

-TransactionForVerification(inStates: List<ContractState>, outStates: List<ContractState>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash)
+TransactionForVerification(inputs: List<TransactionState<ContractState>>, outputs: List<TransactionState<ContractState>>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash, signers: List<PublicKey>, type: TransactionType)

A transaction in fully resolved and sig-checked form, ready for passing as input to a verification function.



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/index.html index eb16604591..466707e09e 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/index.html @@ -11,22 +11,6 @@

A transaction in fully resolved and sig-checked form, ready for passing as input to a verification function.



-

Types

- - - - - - - -
-InOutGroup -data class InOutGroup<T : ContractState, K : Any>

A set of related inputs and outputs that are connected by some common attributes. An InOutGroup is calculated -using groupStates and is useful for handling cases where a transaction may contain similar but unrelated -state evolutions, for example, a transaction that moves cash in two different currencies. The numbers must add -up on both sides of the transaction, but the values must be summed independently per currency. Grouping can -be used to simplify this logic.

-

Constructors

@@ -34,7 +18,7 @@ be used to simplify this logic.

@@ -56,9 +40,9 @@ be used to simplify this logic.

+inputs +val inputs: List<TransactionState<ContractState>> +outputs +val outputs: List<TransactionState<ContractState>> + + + + + + + +
<init> -TransactionForVerification(inStates: List<ContractState>, outStates: List<ContractState>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash)

A transaction in fully resolved and sig-checked form, ready for passing as input to a verification function.

+TransactionForVerification(inputs: List<TransactionState<ContractState>>, outputs: List<TransactionState<ContractState>>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash, signers: List<PublicKey>, type: TransactionType)

A transaction in fully resolved and sig-checked form, ready for passing as input to a verification function.

-inStates -val inStates: List<ContractState>
@@ -68,9 +52,21 @@ be used to simplify this logic.

-outStates -val outStates: List<ContractState>
+signers +val signers: List<PublicKey>
+type +val type: TransactionType
@@ -85,45 +81,21 @@ be used to simplify this logic.

-getTimestampBy - -fun getTimestampBy(timestampingAuthority: Party): TimestampCommand?

Simply calls commands.getTimestampBy as a shortcut to make code completion more intuitive.

- - - - -getTimestampByName - -fun getTimestampByName(vararg authorityName: String): TimestampCommand?

Simply calls commands.getTimestampByName as a shortcut to make code completion more intuitive.

- - - - -groupStates - -fun <T : ContractState, K : Any> groupStates(ofType: Class<T>, selector: (T) -> K): List<InOutGroup<T, K>>

Given a type and a function that returns a grouping key, associates inputs and outputs together so that they -can be processed as one. The grouping key is any arbitrary object that can act as a map key (so must implement -equals and hashCode).

-fun <T : ContractState, K : Any> groupStates(selector: (T) -> K): List<InOutGroup<T, K>>

See the documentation for the reflection-based version of groupStates

- - - - -groupStatesInternal - -fun <T : ContractState, K : Any> groupStatesInternal(inGroups: Map<K, List<T>>, outGroups: Map<K, List<T>>): List<InOutGroup<T, K>> - - - hashCode fun hashCode(): Int +toTransactionForContract + +fun toTransactionForContract(): TransactionForContract + + + verify -fun verify(): Unit

Verifies that the transaction is valid:

+fun verify(): Unit

Verifies that the transaction is valid by running type-specific validation logic.

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/inputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/inputs.html new file mode 100644 index 0000000000..b4e9b297db --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/inputs.html @@ -0,0 +1,15 @@ + + +TransactionForVerification.inputs - + + + +com.r3corda.core.contracts / TransactionForVerification / inputs
+
+

inputs

+ +val inputs: List<TransactionState<ContractState>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/outputs.html new file mode 100644 index 0000000000..377942f9f1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/outputs.html @@ -0,0 +1,15 @@ + + +TransactionForVerification.outputs - + + + +com.r3corda.core.contracts / TransactionForVerification / outputs
+
+

outputs

+ +val outputs: List<TransactionState<ContractState>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/signers.html new file mode 100644 index 0000000000..39cdb34a00 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/signers.html @@ -0,0 +1,15 @@ + + +TransactionForVerification.signers - + + + +com.r3corda.core.contracts / TransactionForVerification / signers
+
+

signers

+ +val signers: List<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/to-transaction-for-contract.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/to-transaction-for-contract.html new file mode 100644 index 0000000000..9402ba4104 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/to-transaction-for-contract.html @@ -0,0 +1,15 @@ + + +TransactionForVerification.toTransactionForContract - + + + +com.r3corda.core.contracts / TransactionForVerification / toTransactionForContract
+
+

toTransactionForContract

+ +fun toTransactionForContract(): TransactionForContract
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/type.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/type.html new file mode 100644 index 0000000000..4701b978a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/type.html @@ -0,0 +1,15 @@ + + +TransactionForVerification.type - + + + +com.r3corda.core.contracts / TransactionForVerification / type
+
+

type

+ +val type: TransactionType
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/verify.html index f4dc759e64..0da45f7da3 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-for-verification/verify.html @@ -9,17 +9,14 @@

verify

fun verify(): Unit
-

Verifies that the transaction is valid:

-
  • Checks that the input states and the timestamp point to the same Notary

    -
  • Runs the contracts for this transaction. If any contract fails to verify, the whole transaction -is considered to be invalid

    -

TODO: Move this out of the core data structure definitions, once unit tests are more cleanly separated.

+

Verifies that the transaction is valid by running type-specific validation logic.

+

TODO: Move this out of the core data structure definitions, once unit tests are more cleanly separated.



Exceptions

-TransactionVerificationException - if a contract throws an exception (the original is in the cause field) -or the transaction has references to more than one Notary
+TransactionVerificationException - if validation logic fails or if a contract throws an exception +(the original is in the cause field)


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/-init-.html index 31823daa39..8cf8a88d68 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / TransactionGraphSearch / <init>

<init>

-TransactionGraphSearch(transactions: TransactionStorage, startPoints: List<WireTransaction>)
+TransactionGraphSearch(transactions: ReadOnlyTransactionStorage, startPoints: List<WireTransaction>)

Given a map of transaction id to SignedTransaction, performs a breadth first search of the dependency graph from the starting point down in order to find transactions that match the given query criteria.

Currently, only one kind of query is supported: find any transaction that contains a command of the given type.

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/index.html index 82a98bfee1..198da1e902 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/index.html @@ -40,7 +40,7 @@ the starting point down in order to find transactions that match the given query <init> -TransactionGraphSearch(transactions: TransactionStorage, startPoints: List<WireTransaction>)

Given a map of transaction id to SignedTransaction, performs a breadth first search of the dependency graph from +TransactionGraphSearch(transactions: ReadOnlyTransactionStorage, startPoints: List<WireTransaction>)

Given a map of transaction id to SignedTransaction, performs a breadth first search of the dependency graph from the starting point down in order to find transactions that match the given query criteria.

@@ -65,7 +65,7 @@ the starting point down in order to find transactions that match the given query transactions -val transactions: TransactionStorage +val transactions: ReadOnlyTransactionStorage diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/transactions.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/transactions.html index 509377a577..9edf4da5cd 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/transactions.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-graph-search/transactions.html @@ -8,7 +8,7 @@

transactions

-val transactions: TransactionStorage
+val transactions: ReadOnlyTransactionStorage


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/-init-.html new file mode 100644 index 0000000000..a0c8154444 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/-init-.html @@ -0,0 +1,16 @@ + + +TransactionState.<init> - + + + +com.r3corda.core.contracts / TransactionState / <init>
+
+

<init>

+TransactionState(data: T, notary: Party)
+

A wrapper for ContractState containing additional platform-level state information. +This is the definitive state that is stored on the ledger and used in transaction outputs.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/data.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/data.html new file mode 100644 index 0000000000..9282d0fd9c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/data.html @@ -0,0 +1,16 @@ + + +TransactionState.data - + + + +com.r3corda.core.contracts / TransactionState / data
+
+

data

+ +val data: T
+

The custom contract state

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/index.html new file mode 100644 index 0000000000..773cb36464 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/index.html @@ -0,0 +1,72 @@ + + +TransactionState - + + + +com.r3corda.core.contracts / TransactionState
+
+

TransactionState

+data class TransactionState<out T : ContractState>
+

A wrapper for ContractState containing additional platform-level state information. +This is the definitive state that is stored on the ledger and used in transaction outputs.

+
+
+

Constructors

+ + + + + + + +
+<init> +TransactionState(data: T, notary: Party)

A wrapper for ContractState containing additional platform-level state information. +This is the definitive state that is stored on the ledger and used in transaction outputs.

+
+

Properties

+ + + + + + + + + + + +
+data +val data: T

The custom contract state

+
+notary +val notary: Party

Identity of the notary that ensures the state is not used as an input to a transaction more than once

+
+

Functions

+ + + + + + + +
+withNewNotary +fun withNewNotary(newNotary: Party): TransactionState<T>

Copies the underlying state, replacing the notary field with the new value. +To replace the notary, we need an approval (signature) from all participants of the ContractState

+
+

Extension Functions

+ + + + + + + +
+label +infix fun TransactionState<*>.label(label: String): LabeledOutput
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/notary.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/notary.html new file mode 100644 index 0000000000..ede4deb099 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/notary.html @@ -0,0 +1,16 @@ + + +TransactionState.notary - + + + +com.r3corda.core.contracts / TransactionState / notary
+
+

notary

+ +val notary: Party
+

Identity of the notary that ensures the state is not used as an input to a transaction more than once

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/with-new-notary.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/with-new-notary.html new file mode 100644 index 0000000000..342ddf25fc --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-state/with-new-notary.html @@ -0,0 +1,17 @@ + + +TransactionState.withNewNotary - + + + +com.r3corda.core.contracts / TransactionState / withNewNotary
+
+

withNewNotary

+ +fun withNewNotary(newNotary: Party): TransactionState<T>
+

Copies the underlying state, replacing the notary field with the new value. +To replace the notary, we need an approval (signature) from all participants of the ContractState

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/-init-.html new file mode 100644 index 0000000000..bcc673c2e5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/-init-.html @@ -0,0 +1,15 @@ + + +TransactionType.General.Builder.<init> - + + + +com.r3corda.core.contracts / TransactionType / General / Builder / <init>
+
+

<init>

+Builder(notary: Party? = null)
+

Just uses the default TransactionBuilder with no special logic

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/index.html new file mode 100644 index 0000000000..ea582cc3a6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-builder/index.html @@ -0,0 +1,200 @@ + + +TransactionType.General.Builder - + + + +com.r3corda.core.contracts / TransactionType / General / Builder
+
+

Builder

+class Builder : TransactionBuilder
+

Just uses the default TransactionBuilder with no special logic

+
+
+

Constructors

+ + + + + + + +
+<init> +Builder(notary: Party? = null)

Just uses the default TransactionBuilder with no special logic

+
+

Inherited Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+attachments +val attachments: MutableList<SecureHash>
+commands +val commands: MutableList<Command>
+currentSigs +val currentSigs: <ERROR CLASS>

The signatures that have been collected so far - might be incomplete

+
+inputs +val inputs: MutableList<StateRef>
+notary +val notary: Party?
+outputs +val outputs: MutableList<TransactionState<ContractState>>
+signers +val signers: MutableSet<PublicKey>
+time +val time: TimestampCommand?
+type +val type: TransactionType
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+addAttachment +fun addAttachment(attachment: Attachment): Unit
+addCommand +fun addCommand(arg: Command): Unit
+fun addCommand(data: CommandData, vararg keys: PublicKey): <ERROR CLASS>
+fun addCommand(data: CommandData, keys: List<PublicKey>): Unit
+addInputState +open fun addInputState(stateAndRef: StateAndRef<*>): Unit
+addOutputState +fun addOutputState(state: TransactionState<*>): Unit
+fun addOutputState(state: ContractState, notary: Party): Unitfun addOutputState(state: ContractState): Unit

A default notary must be specified during builder construction to use this method

+
+addSignatureUnchecked +fun addSignatureUnchecked(sig: WithKey): Unit

Adds the signature directly to the transaction, without checking it for validity.

+
+attachments +fun attachments(): List<SecureHash>
+checkAndAddSignature +fun checkAndAddSignature(sig: WithKey): Unit

Checks that the given signature matches one of the commands and that it is a correct signature over the tx, then +adds it.

+
+checkSignature +fun checkSignature(sig: WithKey): Unit

Checks that the given signature matches one of the commands and that it is a correct signature over the tx.

+
+commands +fun commands(): List<Command>
+inputStates +fun inputStates(): List<StateRef>
+outputStates +fun outputStates(): List<TransactionState<*>>
+setTime +fun setTime(time: Instant, authority: Party, timeTolerance: Duration): Unit

Places a TimestampCommand in this transaction, removing any existing command if there is one. +The command requires a signature from the Notary service, which acts as a Timestamp Authority. +The signature can be obtained using NotaryProtocol.

+
+signWith +fun signWith(key: KeyPair): Unit
+toSignedTransaction +fun toSignedTransaction(checkSufficientSignatures: Boolean = true): SignedTransaction
+toWireTransaction +fun toWireTransaction(): WireTransaction
+withItems +fun withItems(vararg items: Any): TransactionBuilder

A more convenient way to add items to this transaction that calls the add* methods for you based on type

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-init-.html new file mode 100644 index 0000000000..eaabe68ed1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/-init-.html @@ -0,0 +1,15 @@ + + +TransactionType.General.<init> - + + + +com.r3corda.core.contracts / TransactionType / General / <init>
+
+

<init>

+General()
+

A general transaction type where transaction validity is determined by custom contract code

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/get-required-signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/get-required-signers.html new file mode 100644 index 0000000000..f8f3e117b7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/get-required-signers.html @@ -0,0 +1,18 @@ + + +TransactionType.General.getRequiredSigners - + + + +com.r3corda.core.contracts / TransactionType / General / getRequiredSigners
+
+

getRequiredSigners

+ +fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>
+Overrides TransactionType.getRequiredSigners
+

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/index.html new file mode 100644 index 0000000000..aaff72fddc --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/index.html @@ -0,0 +1,91 @@ + + +TransactionType.General - + + + +com.r3corda.core.contracts / TransactionType / General
+
+

General

+class General : TransactionType
+

A general transaction type where transaction validity is determined by custom contract code

+
+
+

Types

+ + + + + + + +
+Builder +class Builder : TransactionBuilder

Just uses the default TransactionBuilder with no special logic

+
+

Constructors

+ + + + + + + +
+<init> +General()

A general transaction type where transaction validity is determined by custom contract code

+
+

Functions

+ + + + + + + + + + + +
+getRequiredSigners +fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+verifyTransaction +fun verifyTransaction(tx: TransactionForVerification): Unit

Check the transaction is contract-valid by running the verify() for each input and output state contract. +If any contract fails to verify, the whole transaction is considered to be invalid

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + +
+equals +open fun equals(other: Any?): Boolean
+hashCode +open fun hashCode(): <ERROR CLASS>
+verify +fun verify(tx: TransactionForVerification): Unit

Check that the transaction is valid based on:

+
+verifySigners +fun verifySigners(tx: TransactionForVerification): Set<PublicKey>

Check that the list of signers includes all the necessary keys

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/verify-transaction.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/verify-transaction.html new file mode 100644 index 0000000000..9903d6ba36 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-general/verify-transaction.html @@ -0,0 +1,18 @@ + + +TransactionType.General.verifyTransaction - + + + +com.r3corda.core.contracts / TransactionType / General / verifyTransaction
+
+

verifyTransaction

+ +fun verifyTransaction(tx: TransactionForVerification): Unit
+Overrides TransactionType.verifyTransaction
+

Check the transaction is contract-valid by running the verify() for each input and output state contract. +If any contract fails to verify, the whole transaction is considered to be invalid

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/-init-.html new file mode 100644 index 0000000000..1f23f39a59 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/-init-.html @@ -0,0 +1,16 @@ + + +TransactionType.NotaryChange.Builder.<init> - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / Builder / <init>
+
+

<init>

+Builder(notary: Party? = null)
+

A transaction builder that automatically sets the transaction type to NotaryChange +and adds the list of participants to the signers set for every input state.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/add-input-state.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/add-input-state.html new file mode 100644 index 0000000000..96ab591cc3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/add-input-state.html @@ -0,0 +1,16 @@ + + +TransactionType.NotaryChange.Builder.addInputState - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / Builder / addInputState
+
+

addInputState

+ +fun addInputState(stateAndRef: StateAndRef<*>): Unit
+Overrides TransactionBuilder.addInputState
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/index.html new file mode 100644 index 0000000000..5e19c55e1a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-builder/index.html @@ -0,0 +1,207 @@ + + +TransactionType.NotaryChange.Builder - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / Builder
+
+

Builder

+class Builder : TransactionBuilder
+

A transaction builder that automatically sets the transaction type to NotaryChange +and adds the list of participants to the signers set for every input state.

+
+
+

Constructors

+ + + + + + + +
+<init> +Builder(notary: Party? = null)

A transaction builder that automatically sets the transaction type to NotaryChange +and adds the list of participants to the signers set for every input state.

+
+

Inherited Properties

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+attachments +val attachments: MutableList<SecureHash>
+commands +val commands: MutableList<Command>
+currentSigs +val currentSigs: <ERROR CLASS>

The signatures that have been collected so far - might be incomplete

+
+inputs +val inputs: MutableList<StateRef>
+notary +val notary: Party?
+outputs +val outputs: MutableList<TransactionState<ContractState>>
+signers +val signers: MutableSet<PublicKey>
+time +val time: TimestampCommand?
+type +val type: TransactionType
+

Functions

+ + + + + + + +
+addInputState +fun addInputState(stateAndRef: StateAndRef<*>): Unit
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+addAttachment +fun addAttachment(attachment: Attachment): Unit
+addCommand +fun addCommand(arg: Command): Unit
+fun addCommand(data: CommandData, vararg keys: PublicKey): <ERROR CLASS>
+fun addCommand(data: CommandData, keys: List<PublicKey>): Unit
+addOutputState +fun addOutputState(state: TransactionState<*>): Unit
+fun addOutputState(state: ContractState, notary: Party): Unitfun addOutputState(state: ContractState): Unit

A default notary must be specified during builder construction to use this method

+
+addSignatureUnchecked +fun addSignatureUnchecked(sig: WithKey): Unit

Adds the signature directly to the transaction, without checking it for validity.

+
+attachments +fun attachments(): List<SecureHash>
+checkAndAddSignature +fun checkAndAddSignature(sig: WithKey): Unit

Checks that the given signature matches one of the commands and that it is a correct signature over the tx, then +adds it.

+
+checkSignature +fun checkSignature(sig: WithKey): Unit

Checks that the given signature matches one of the commands and that it is a correct signature over the tx.

+
+commands +fun commands(): List<Command>
+inputStates +fun inputStates(): List<StateRef>
+outputStates +fun outputStates(): List<TransactionState<*>>
+setTime +fun setTime(time: Instant, authority: Party, timeTolerance: Duration): Unit

Places a TimestampCommand in this transaction, removing any existing command if there is one. +The command requires a signature from the Notary service, which acts as a Timestamp Authority. +The signature can be obtained using NotaryProtocol.

+
+signWith +fun signWith(key: KeyPair): Unit
+toSignedTransaction +fun toSignedTransaction(checkSufficientSignatures: Boolean = true): SignedTransaction
+toWireTransaction +fun toWireTransaction(): WireTransaction
+withItems +fun withItems(vararg items: Any): TransactionBuilder

A more convenient way to add items to this transaction that calls the add* methods for you based on type

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-init-.html new file mode 100644 index 0000000000..f188ceeb25 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/-init-.html @@ -0,0 +1,16 @@ + + +TransactionType.NotaryChange.<init> - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / <init>
+
+

<init>

+NotaryChange()
+

A special transaction type for reassigning a notary for a state. Validation does not involve running +any contract code, it just checks that the states are unmodified apart from the notary field.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/get-required-signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/get-required-signers.html new file mode 100644 index 0000000000..1db269a937 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/get-required-signers.html @@ -0,0 +1,18 @@ + + +TransactionType.NotaryChange.getRequiredSigners - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / getRequiredSigners
+
+

getRequiredSigners

+ +fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>
+Overrides TransactionType.getRequiredSigners
+

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/index.html new file mode 100644 index 0000000000..73c0837fab --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/index.html @@ -0,0 +1,94 @@ + + +TransactionType.NotaryChange - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange
+
+

NotaryChange

+class NotaryChange : TransactionType
+

A special transaction type for reassigning a notary for a state. Validation does not involve running +any contract code, it just checks that the states are unmodified apart from the notary field.

+
+
+

Types

+ + + + + + + +
+Builder +class Builder : TransactionBuilder

A transaction builder that automatically sets the transaction type to NotaryChange +and adds the list of participants to the signers set for every input state.

+
+

Constructors

+ + + + + + + +
+<init> +NotaryChange()

A special transaction type for reassigning a notary for a state. Validation does not involve running +any contract code, it just checks that the states are unmodified apart from the notary field.

+
+

Functions

+ + + + + + + + + + + +
+getRequiredSigners +fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+verifyTransaction +fun verifyTransaction(tx: TransactionForVerification): Unit

Check that the difference between inputs and outputs is only the notary field, +and that all required signing public keys are present

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + +
+equals +open fun equals(other: Any?): Boolean
+hashCode +open fun hashCode(): <ERROR CLASS>
+verify +fun verify(tx: TransactionForVerification): Unit

Check that the transaction is valid based on:

+
+verifySigners +fun verifySigners(tx: TransactionForVerification): Set<PublicKey>

Check that the list of signers includes all the necessary keys

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/verify-transaction.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/verify-transaction.html new file mode 100644 index 0000000000..a208072678 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/-notary-change/verify-transaction.html @@ -0,0 +1,18 @@ + + +TransactionType.NotaryChange.verifyTransaction - + + + +com.r3corda.core.contracts / TransactionType / NotaryChange / verifyTransaction
+
+

verifyTransaction

+ +fun verifyTransaction(tx: TransactionForVerification): Unit
+Overrides TransactionType.verifyTransaction
+

Check that the difference between inputs and outputs is only the notary field, +and that all required signing public keys are present

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/equals.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/equals.html new file mode 100644 index 0000000000..d6960ac1c4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/equals.html @@ -0,0 +1,15 @@ + + +TransactionType.equals - + + + +com.r3corda.core.contracts / TransactionType / equals
+
+

equals

+ +open fun equals(other: Any?): Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/get-required-signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/get-required-signers.html new file mode 100644 index 0000000000..0dfce701c2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/get-required-signers.html @@ -0,0 +1,17 @@ + + +TransactionType.getRequiredSigners - + + + +com.r3corda.core.contracts / TransactionType / getRequiredSigners
+
+

getRequiredSigners

+ +abstract fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>
+

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/hash-code.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/hash-code.html new file mode 100644 index 0000000000..e8d52895a8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/hash-code.html @@ -0,0 +1,15 @@ + + +TransactionType.hashCode - + + + +com.r3corda.core.contracts / TransactionType / hashCode
+
+

hashCode

+ +open fun hashCode(): <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/index.html new file mode 100644 index 0000000000..88315146bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/index.html @@ -0,0 +1,101 @@ + + +TransactionType - + + + +com.r3corda.core.contracts / TransactionType
+
+

TransactionType

+sealed class TransactionType
+

Defines transaction build & validation logic for a specific transaction type

+
+
+

Types

+ + + + + + + + + + + +
+General +class General : TransactionType

A general transaction type where transaction validity is determined by custom contract code

+
+NotaryChange +class NotaryChange : TransactionType

A special transaction type for reassigning a notary for a state. Validation does not involve running +any contract code, it just checks that the states are unmodified apart from the notary field.

+
+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
+equals +open fun equals(other: Any?): Boolean
+getRequiredSigners +abstract fun getRequiredSigners(tx: TransactionForVerification): Set<PublicKey>

Return the list of public keys that that require signatures for the transaction type. +Note: the notary key is checked separately for all transactions and need not be included

+
+hashCode +open fun hashCode(): <ERROR CLASS>
+verify +fun verify(tx: TransactionForVerification): Unit

Check that the transaction is valid based on:

+
+verifySigners +fun verifySigners(tx: TransactionForVerification): Set<PublicKey>

Check that the list of signers includes all the necessary keys

+
+verifyTransaction +abstract fun verifyTransaction(tx: TransactionForVerification): Unit

Implement type specific transaction validation logic

+
+

Inheritors

+ + + + + + + + + + + +
+General +class General : TransactionType

A general transaction type where transaction validity is determined by custom contract code

+
+NotaryChange +class NotaryChange : TransactionType

A special transaction type for reassigning a notary for a state. Validation does not involve running +any contract code, it just checks that the states are unmodified apart from the notary field.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-signers.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-signers.html new file mode 100644 index 0000000000..46b5b6f76e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-signers.html @@ -0,0 +1,16 @@ + + +TransactionType.verifySigners - + + + +com.r3corda.core.contracts / TransactionType / verifySigners
+
+

verifySigners

+ +fun verifySigners(tx: TransactionForVerification): Set<PublicKey>
+

Check that the list of signers includes all the necessary keys

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-transaction.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-transaction.html new file mode 100644 index 0000000000..522e3fe365 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify-transaction.html @@ -0,0 +1,16 @@ + + +TransactionType.verifyTransaction - + + + +com.r3corda.core.contracts / TransactionType / verifyTransaction
+
+

verifyTransaction

+ +abstract fun verifyTransaction(tx: TransactionForVerification): Unit
+

Implement type specific transaction validation logic

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify.html new file mode 100644 index 0000000000..b12ac7e8c4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-type/verify.html @@ -0,0 +1,21 @@ + + +TransactionType.verify - + + + +com.r3corda.core.contracts / TransactionType / verify
+
+

verify

+ +fun verify(tx: TransactionForVerification): Unit
+

Check that the transaction is valid based on:

+
  • General platform rules

    +
  • Rules for the specific transaction type

    +

Note: Presence of signatures is not checked, only the public keys to be signed for.

+
+
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/-init-.html new file mode 100644 index 0000000000..53d5735b7f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/-init-.html @@ -0,0 +1,14 @@ + + +TransactionVerificationException.InvalidNotaryChange.<init> - + + + +com.r3corda.core.contracts / TransactionVerificationException / InvalidNotaryChange / <init>
+
+

<init>

+InvalidNotaryChange(tx: TransactionForVerification)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/index.html new file mode 100644 index 0000000000..a4382418e2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-invalid-notary-change/index.html @@ -0,0 +1,36 @@ + + +TransactionVerificationException.InvalidNotaryChange - + + + +com.r3corda.core.contracts / TransactionVerificationException / InvalidNotaryChange
+
+

InvalidNotaryChange

+class InvalidNotaryChange : TransactionVerificationException
+
+
+

Constructors

+ + + + + + + +
+<init> +InvalidNotaryChange(tx: TransactionForVerification)
+

Inherited Properties

+ + + + + + + +
+tx +val tx: TransactionForVerification
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/-init-.html new file mode 100644 index 0000000000..1b23a7c3f6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/-init-.html @@ -0,0 +1,14 @@ + + +TransactionVerificationException.SignersMissing.<init> - + + + +com.r3corda.core.contracts / TransactionVerificationException / SignersMissing / <init>
+
+

<init>

+SignersMissing(tx: TransactionForVerification, missing: List<PublicKey>)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/index.html new file mode 100644 index 0000000000..05d27eb3d1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/-signers-missing/index.html @@ -0,0 +1,36 @@ + + +TransactionVerificationException.SignersMissing - + + + +com.r3corda.core.contracts / TransactionVerificationException / SignersMissing
+
+

SignersMissing

+class SignersMissing : TransactionVerificationException
+
+
+

Constructors

+ + + + + + + +
+<init> +SignersMissing(tx: TransactionForVerification, missing: List<PublicKey>)
+

Inherited Properties

+ + + + + + + +
+tx +val tx: TransactionForVerification
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/index.html b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/index.html index 32267c16e2..2a2f62dd72 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-transaction-verification-exception/index.html @@ -21,10 +21,22 @@ +InvalidNotaryChange + +class InvalidNotaryChange : TransactionVerificationException + + + MoreThanOneNotary class MoreThanOneNotary : TransactionVerificationException + + +SignersMissing + +class SignersMissing : TransactionVerificationException +

Properties

@@ -49,10 +61,22 @@ +InvalidNotaryChange + +class InvalidNotaryChange : TransactionVerificationException + + + MoreThanOneNotary class MoreThanOneNotary : TransactionVerificationException + + +SignersMissing + +class SignersMissing : TransactionVerificationException + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-type-only-command-data/index.html b/docs/build/html/api/com.r3corda.core.contracts/-type-only-command-data/index.html index 67efeab009..e2bc710ee6 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-type-only-command-data/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-type-only-command-data/index.html @@ -75,9 +75,9 @@ -Move +Move -class Move : TypeOnlyCommandData, Move +class Move : TypeOnlyCommandData, Commands diff --git a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/-init-.html index 7344247951..2c42283bf9 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / WireTransaction / <init>

<init>

-WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<ContractState>, commands: List<Command>)
+WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<TransactionState<ContractState>>, commands: List<Command>, signers: List<PublicKey>, type: TransactionType)

Transaction ready for serialisation, without any signatures attached.



diff --git a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/index.html b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/index.html index 5323ea23ff..34d702e991 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/index.html @@ -18,7 +18,7 @@ <init> -WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<ContractState>, commands: List<Command>)

Transaction ready for serialisation, without any signatures attached.

+WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<TransactionState<ContractState>>, commands: List<Command>, signers: List<PublicKey>, type: TransactionType)

Transaction ready for serialisation, without any signatures attached.

@@ -54,7 +54,7 @@ outputs -val outputs: List<ContractState> +val outputs: List<TransactionState<ContractState>> @@ -62,6 +62,18 @@ val serialized: SerializedBytes<WireTransaction> + + +signers + +val signers: List<PublicKey> + + + +type + +val type: TransactionType +

Functions

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/outputs.html b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/outputs.html index c480b02af7..c40c443489 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/outputs.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/outputs.html @@ -8,7 +8,7 @@

outputs

-val outputs: List<ContractState>
+val outputs: List<TransactionState<ContractState>>


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/signers.html b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/signers.html new file mode 100644 index 0000000000..a7ffee8878 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/signers.html @@ -0,0 +1,15 @@ + + +WireTransaction.signers - + + + +com.r3corda.core.contracts / WireTransaction / signers
+
+

signers

+ +val signers: List<PublicKey>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/type.html b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/type.html new file mode 100644 index 0000000000..80029b131a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-wire-transaction/type.html @@ -0,0 +1,15 @@ + + +WireTransaction.type - + + + +com.r3corda.core.contracts / WireTransaction / type
+
+

type

+ +val type: TransactionType
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/currency.html b/docs/build/html/api/com.r3corda.core.contracts/currency.html index 8161420868..8827660e1b 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/currency.html +++ b/docs/build/html/api/com.r3corda.core.contracts/currency.html @@ -9,7 +9,7 @@

currency

fun currency(code: String): Currency
-

Defines a simple domain specific language for the specificiation of financial contracts. Currently covers:

+

Defines a simple domain specific language for the specification of financial contracts. Currently covers:

  • Some utilities for working with commands.

  • Code for working with currencies.

  • An Amount type that represents a positive quantity of a specific currency.

    diff --git a/docs/build/html/api/com.r3corda.core.contracts/index.html b/docs/build/html/api/com.r3corda.core.contracts/index.html index 5fecc707d7..17b5c043b0 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/index.html @@ -45,6 +45,13 @@ of how attachments are meant to be used include:

    +BilateralNettableState + +interface BilateralNettableState<T : BilateralNettableState<T>>

    Interface for state objects that support being netted with other state objects.

    + + + + BusinessCalendar open class BusinessCalendar

    A business calendar performs date calculations that take into account national holidays and weekends. This is a @@ -82,15 +89,9 @@ timestamp attached to the transaction itself i.e. it is NOT necessarily the curr interface ContractState

    A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk file that the program can use to persist data across transactions. States are immutable: once created they are never -updated, instead, any changes must generate a new successor state.

    - - - - -DateOffset - -enum class DateOffset

    Date offset that the fixing is done prior to the accrual start date. -Currently not used in the calculation.

    +updated, instead, any changes must generate a new successor state. States can be updated (consumed) only once: the +notary is responsible for ensuring there is no "double spending" by only signing a transaction if the input states +are all free.

    @@ -142,6 +143,13 @@ implementation of general protocols that manipulate many agreement types.

    +DummyState + +data class DummyState : ContractState

    Dummy state for use in testing. Not part of any real contract.

    + + + + Expression data class Expression

    Represents a textual expression of e.g. a formula

    @@ -198,6 +206,27 @@ from which the state object is initialised.

    +IssueCommand + +interface IssueCommand : CommandData

    A common issue command, to enforce that issue commands have a nonce value.

    + + + + +Issued + +data class Issued<P>

    Definition for an issued product, which can be cash, a cash-like thing, assets, or generally anything else thats +quantifiable with integer quantities.

    + + + + +JavaTestHelpers + +object JavaTestHelpers + + + LedgerTransaction data class LedgerTransaction : NamedByHash

    A LedgerTransaction wraps the data needed to calculate one or more successor states from a set of input states. @@ -214,6 +243,13 @@ with the commands from the wire, and verified/looked up.

    +MoveCommand + +interface MoveCommand : CommandData

    A common move command for contracts which can change owner.

    + + + + NamedByHash interface NamedByHash

    Implemented by anything that can be named by a secure hash value (e.g. transactions, attachments).

    @@ -221,6 +257,14 @@ with the commands from the wire, and verified/looked up.

    +NetType + +enum class NetType

    Enum for the types of netting that can be applied to state objects. Exact behaviour +for each type of netting is left to the contract to determine.

    + + + + OwnableState interface OwnableState : ContractState

    A contract state that can have a single owner.

    @@ -249,6 +293,35 @@ ledger. The reference is intended to be encrypted so its meaningless to anyone o +SchedulableState + +interface SchedulableState : ContractState + + + +Scheduled + +interface Scheduled

    Something which is scheduled to happen at a point in time

    + + + + +ScheduledActivity + +data class ScheduledActivity : Scheduled

    This class represents the lifecycle activity that a contract state of type LinearState would like to perform at a given point in time. +e.g. run a fixing protocol

    + + + + +ScheduledStateRef + +data class ScheduledStateRef : Scheduled

    Represents a contract state (unconsumed output) of type LinearState and a point in time that a lifecycle event is expected to take place +for that contract state.

    + + + + SignedTransaction data class SignedTransaction : NamedByHash

    Container for a WireTransaction and attached signatures.

    @@ -288,10 +361,17 @@ public keys are identified in the containing Comma TransactionBuilder -class TransactionBuilder

    A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is -intended to be passed around contracts that may edit it by adding new states/commands or modifying the existing set. -Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from -multiple parties.

    +abstract class TransactionBuilder

    A TransactionBuilder is a transaction class thats mutable (unlike the others which are all immutable). It is +intended to be passed around contracts that may edit it by adding new states/commands. Then once the states +and commands are right, this class can be used as a holding bucket to gather signatures from multiple parties.

    + + + + +TransactionForContract + +data class TransactionForContract

    A transaction to be passed as input to a contract verification function. Defines helper methods to +simplify verification logic in contracts.

    @@ -320,6 +400,21 @@ this subgraph does not contain conflicts and is accepted by the involved contrac +TransactionState + +data class TransactionState<out T : ContractState>

    A wrapper for ContractState containing additional platform-level state information. +This is the definitive state that is stored on the ledger and used in transaction outputs.

    + + + + +TransactionType + +sealed class TransactionType

    Defines transaction build & validation logic for a specific transaction type

    + + + + TypeOnlyCommandData abstract class TypeOnlyCommandData : CommandData

    Commands that inherit from this are intended to have no data items: its only their presence that matters.

    @@ -368,6 +463,12 @@ this subgraph does not contain conflicts and is accepted by the involved contrac +java.util.Currency + + + + + kotlin.Double @@ -440,7 +541,7 @@ this subgraph does not contain conflicts and is accepted by the involved contrac currency -fun currency(code: String): Currency

    Defines a simple domain specific language for the specificiation of financial contracts. Currently covers:

    +fun currency(code: String): Currency

    Defines a simple domain specific language for the specification of financial contracts. Currently covers:

    @@ -452,6 +553,12 @@ this subgraph does not contain conflicts and is accepted by the involved contrac +issued by + +infix fun Amount<Currency>.issued by(deposit: PartyAndReference): Amount<Issued<Currency>> + + + requireThat fun <R> requireThat(body: Requirements.() -> R): R @@ -465,9 +572,10 @@ this subgraph does not contain conflicts and is accepted by the involved contrac -verifyMoveCommands +verifyMoveCommand -fun <T : CommandData> verifyMoveCommands(inputs: List<OwnableState>, tx: TransactionForVerification): Unit

    Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.

    +fun <T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, tx: TransactionForContract): Unit
    +fun <T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, commands: List<AuthenticatedObject<CommandData>>): Unit

    Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.

    diff --git a/docs/build/html/api/com.r3corda.core.contracts/issued by.html b/docs/build/html/api/com.r3corda.core.contracts/issued by.html new file mode 100644 index 0000000000..15f0831011 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/issued by.html @@ -0,0 +1,15 @@ + + +issued by - + + + +com.r3corda.core.contracts / issued by
    +
    +

    issued by

    + +infix fun Amount<Currency>.issued by(deposit: PartyAndReference): Amount<Issued<Currency>>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/index.html b/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/index.html new file mode 100644 index 0000000000..078d92a92b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/index.html @@ -0,0 +1,21 @@ + + +com.r3corda.core.contracts.java.util.Currency - + + + +com.r3corda.core.contracts / java.util.Currency
    +
    +

    Extensions for java.util.Currency

    + + + + + + + +
    +issued by +infix fun Currency.issued by(deposit: PartyAndReference): Issued<Currency>
    + + diff --git a/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/issued by.html b/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/issued by.html new file mode 100644 index 0000000000..5e3e67e7c7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/java.util.-currency/issued by.html @@ -0,0 +1,15 @@ + + +issued by - + + + +com.r3corda.core.contracts / java.util.Currency / issued by
    +
    +

    issued by

    + +infix fun Currency.issued by(deposit: PartyAndReference): Issued<Currency>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.contracts/verify-move-command.html b/docs/build/html/api/com.r3corda.core.contracts/verify-move-command.html new file mode 100644 index 0000000000..4ea9ee100d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/verify-move-command.html @@ -0,0 +1,21 @@ + + +verifyMoveCommand - + + + +com.r3corda.core.contracts / verifyMoveCommand
    +
    +

    verifyMoveCommand

    + +inline fun <reified T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, tx: TransactionForContract): Unit
    + +inline fun <reified T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, commands: List<AuthenticatedObject<CommandData>>): Unit
    +

    Simple functionality for verifying a move command. Verifies that each input has a signature from its owning key.

    +

    Parameters

    + +T - the type of the move command
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.crypto/generate-key-pair.html b/docs/build/html/api/com.r3corda.core.crypto/generate-key-pair.html index cbee03c2dd..b38bd5802b 100644 --- a/docs/build/html/api/com.r3corda.core.crypto/generate-key-pair.html +++ b/docs/build/html/api/com.r3corda.core.crypto/generate-key-pair.html @@ -8,7 +8,7 @@

    generateKeyPair

    -fun generateKeyPair(): KeyPair
    +fun generateKeyPair(): <ERROR CLASS>

    A simple wrapper that will make it easier to swap out the EC algorithm we use in future



    diff --git a/docs/build/html/api/com.r3corda.core.crypto/index.html b/docs/build/html/api/com.r3corda.core.crypto/index.html index 34c0e7c860..26adee50d7 100644 --- a/docs/build/html/api/com.r3corda.core.crypto/index.html +++ b/docs/build/html/api/com.r3corda.core.crypto/index.html @@ -90,11 +90,17 @@ contained within.

    generateKeyPair -fun generateKeyPair(): KeyPair

    A simple wrapper that will make it easier to swap out the EC algorithm we use in future

    +fun generateKeyPair(): <ERROR CLASS>

    A simple wrapper that will make it easier to swap out the EC algorithm we use in future

    +newSecureRandom + +fun newSecureRandom(): SecureRandom + + + sha256 fun OpaqueBytes.sha256(): SHA256 diff --git a/docs/build/html/api/com.r3corda.core.crypto/new-secure-random.html b/docs/build/html/api/com.r3corda.core.crypto/new-secure-random.html new file mode 100644 index 0000000000..b2828bae9e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.crypto/new-secure-random.html @@ -0,0 +1,15 @@ + + +newSecureRandom - + + + +com.r3corda.core.crypto / newSecureRandom
    +
    +

    newSecureRandom

    + +fun newSecureRandom(): SecureRandom
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.messaging/-ack.html b/docs/build/html/api/com.r3corda.core.messaging/-ack.html new file mode 100644 index 0000000000..4ab479fc9a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.messaging/-ack.html @@ -0,0 +1,16 @@ + + +Ack - + + + +com.r3corda.core.messaging / Ack
    +
    +

    Ack

    +object Ack : DeserializeAsKotlinObjectDef
    +

    A general Ack message that conveys no content other than its presence for use when you want an acknowledgement +from a recipient. Using Unit can be ambiguous as it is similar to Void and so could mean no response.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.messaging/index.html b/docs/build/html/api/com.r3corda.core.messaging/index.html index c997a762b5..c0a7bd6dce 100644 --- a/docs/build/html/api/com.r3corda.core.messaging/index.html +++ b/docs/build/html/api/com.r3corda.core.messaging/index.html @@ -12,6 +12,14 @@ +Ack + +object Ack : DeserializeAsKotlinObjectDef

    A general Ack message that conveys no content other than its presence for use when you want an acknowledgement +from a recipient. Using Unit can be ambiguous as it is similar to Void and so could mean no response.

    + + + + AllPossibleRecipients interface AllPossibleRecipients : MessageRecipients

    A special base class for the set of all possible recipients, without having to identify who they all are.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/index.html b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/index.html index 68951a71a0..dd67c061d4 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/index.html @@ -47,10 +47,8 @@ operation due to the need to copy the bytes to disk and hash them along the way. openAttachment -fun openAttachment(id: SecureHash): Attachment?

    Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

    +fun openAttachment(id: SecureHash): Attachment?

    Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/open-attachment.html b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/open-attachment.html index 83881f585c..82b57d800d 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/open-attachment.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-attachment-storage/open-attachment.html @@ -10,10 +10,8 @@ fun openAttachment(id: SecureHash): Attachment?
    Overrides AttachmentStorage.openAttachment
    -

    Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

    +

    Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.



    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/index.html b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/index.html index 720872b62d..d033940e28 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/index.html @@ -7,7 +7,7 @@ com.r3corda.core.node.services.testing / MockStorageService

    MockStorageService

    -class MockStorageService : SingletonSerializeAsToken, StorageService
    +class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService


    Constructors

    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/validated-transactions.html b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/validated-transactions.html index 95345c0308..c91ef2bebf 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/validated-transactions.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-storage-service/validated-transactions.html @@ -9,7 +9,7 @@

    validatedTransactions

    val validatedTransactions: TransactionStorage
    -Overrides StorageService.validatedTransactions
    +Overrides TxWritableStorageService.validatedTransactions

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. The signatures arent technically needed after that point, but we keep them around so that we can relay the transaction data to other nodes that need it.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-transaction-storage/get-transaction.html b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-transaction-storage/get-transaction.html index ec2be5c7db..e50af76719 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-transaction-storage/get-transaction.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/-mock-transaction-storage/get-transaction.html @@ -9,7 +9,7 @@

    getTransaction

    open fun getTransaction(id: SecureHash): SignedTransaction?
    -Overrides TransactionStorage.getTransaction
    +Overrides ReadOnlyTransactionStorage.getTransaction

    Return the transaction with the given id, or null if no such transaction exists.



    diff --git a/docs/build/html/api/com.r3corda.core.node.services.testing/index.html b/docs/build/html/api/com.r3corda.core.node.services.testing/index.html index 4d41f89fd6..435aae0e05 100644 --- a/docs/build/html/api/com.r3corda.core.node.services.testing/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services.testing/index.html @@ -32,7 +32,7 @@ MockStorageService -class MockStorageService : SingletonSerializeAsToken, StorageService +class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService diff --git a/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/index.html b/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/index.html index d3f8a6011c..008415df37 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/index.html @@ -8,8 +8,7 @@

    AttachmentStorage

    interface AttachmentStorage
    -

    An attachment store records potentially large binary objects, identified by their hash. Note that attachments are -immutable and can never be erased once inserted

    +

    An attachment store records potentially large binary objects, identified by their hash.



    Functions

    @@ -27,10 +26,8 @@ operation due to the need to copy the bytes to disk and hash them along the way. openAttachment -abstract fun openAttachment(id: SecureHash): Attachment?

    Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

    +abstract fun openAttachment(id: SecureHash): Attachment?

    Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/open-attachment.html b/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/open-attachment.html index d39ae99d17..8c8aceecfd 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/open-attachment.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-attachment-storage/open-attachment.html @@ -9,10 +9,8 @@

    openAttachment

    abstract fun openAttachment(id: SecureHash): Attachment?
    -

    Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

    +

    Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.



    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/get-transaction.html b/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/get-transaction.html new file mode 100644 index 0000000000..d9aaeed402 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/get-transaction.html @@ -0,0 +1,16 @@ + + +ReadOnlyTransactionStorage.getTransaction - + + + +com.r3corda.core.node.services / ReadOnlyTransactionStorage / getTransaction
    +
    +

    getTransaction

    + +abstract fun getTransaction(id: SecureHash): SignedTransaction?
    +

    Return the transaction with the given id, or null if no such transaction exists.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/index.html b/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/index.html new file mode 100644 index 0000000000..d48a918cf6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-read-only-transaction-storage/index.html @@ -0,0 +1,39 @@ + + +ReadOnlyTransactionStorage - + + + +com.r3corda.core.node.services / ReadOnlyTransactionStorage
    +
    +

    ReadOnlyTransactionStorage

    +interface ReadOnlyTransactionStorage
    +

    Thread-safe storage of transactions.

    +
    +
    +

    Functions

    + + + + + + + +
    +getTransaction +abstract fun getTransaction(id: SecureHash): SignedTransaction?

    Return the transaction with the given id, or null if no such transaction exists.

    +
    +

    Inheritors

    + + + + + + + +
    +TransactionStorage +interface TransactionStorage : ReadOnlyTransactionStorage

    Thread-safe storage of transactions.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/index.html b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/index.html new file mode 100644 index 0000000000..45874f344b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/index.html @@ -0,0 +1,53 @@ + + +SchedulerService - + + + +com.r3corda.core.node.services / SchedulerService
    +
    +

    SchedulerService

    +interface SchedulerService
    +

    Provides access to schedule activity at some point in time. This interface might well be expanded to +increase the feature set in the future.

    +

    If the point in time is in the past, the expectation is that the activity will happen shortly after it is scheduled.

    +

    The main consumer initially is an observer of the wallet to schedule activities based on transactions as they are +recorded.

    +
    +
    +
    +
    +

    Functions

    + + + + + + + + + + + +
    +scheduleStateActivity +abstract fun scheduleStateActivity(action: ScheduledStateRef): Unit

    Schedule a new activity for a TX output, probably because it was just produced.

    +
    +unscheduleStateActivity +abstract fun unscheduleStateActivity(ref: StateRef): Unit

    Unschedule all activity for a TX output, probably because it was consumed.

    +
    +

    Inheritors

    + + + + + + + +
    +NodeSchedulerService +class NodeSchedulerService : SchedulerService, SingletonSerializeAsToken

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/schedule-state-activity.html b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/schedule-state-activity.html new file mode 100644 index 0000000000..01eb9b8b8c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/schedule-state-activity.html @@ -0,0 +1,20 @@ + + +SchedulerService.scheduleStateActivity - + + + +com.r3corda.core.node.services / SchedulerService / scheduleStateActivity
    +
    +

    scheduleStateActivity

    + +abstract fun scheduleStateActivity(action: ScheduledStateRef): Unit
    +

    Schedule a new activity for a TX output, probably because it was just produced.

    +

    Only one activity can be scheduled for a particular StateRef at any one time. Scheduling a ScheduledStateRef +replaces any previously scheduled ScheduledStateRef for any one StateRef.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/unschedule-state-activity.html b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/unschedule-state-activity.html new file mode 100644 index 0000000000..8ce0c44839 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-scheduler-service/unschedule-state-activity.html @@ -0,0 +1,16 @@ + + +SchedulerService.unscheduleStateActivity - + + + +com.r3corda.core.node.services / SchedulerService / unscheduleStateActivity
    +
    +

    unscheduleStateActivity

    + +abstract fun unscheduleStateActivity(ref: StateRef): Unit
    +

    Unschedule all activity for a TX output, probably because it was consumed.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-storage-service/index.html b/docs/build/html/api/com.r3corda.core.node.services/-storage-service/index.html index 6476695f86..31570ced80 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-storage-service/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-storage-service/index.html @@ -41,7 +41,7 @@ first installed.

    validatedTransactions -abstract val validatedTransactions: TransactionStorage

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. +abstract val validatedTransactions: ReadOnlyTransactionStorage

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. The signatures arent technically needed after that point, but we keep them around so that we can relay the transaction data to other nodes that need it.

    @@ -53,15 +53,10 @@ the transaction data to other nodes that need it.

    -MockStorageService +TxWritableStorageService -class MockStorageService : SingletonSerializeAsToken, StorageService - - - -StorageServiceImpl - -open class StorageServiceImpl : SingletonSerializeAsToken, StorageService +interface TxWritableStorageService : StorageService

    Storage service, with extensions to allow validated transactions to be added to. For use only within ServiceHub.

    + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-storage-service/validated-transactions.html b/docs/build/html/api/com.r3corda.core.node.services/-storage-service/validated-transactions.html index 9da34f2922..71a78bb151 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-storage-service/validated-transactions.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-storage-service/validated-transactions.html @@ -8,7 +8,7 @@

    validatedTransactions

    -abstract val validatedTransactions: TransactionStorage
    +abstract val validatedTransactions: ReadOnlyTransactionStorage

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. The signatures arent technically needed after that point, but we keep them around so that we can relay the transaction data to other nodes that need it.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-transaction-storage/index.html b/docs/build/html/api/com.r3corda.core.node.services/-transaction-storage/index.html index d03a4902ea..8fbaa5dcdb 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-transaction-storage/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-transaction-storage/index.html @@ -7,7 +7,7 @@ com.r3corda.core.node.services / TransactionStorage

    TransactionStorage

    -interface TransactionStorage
    +interface TransactionStorage : ReadOnlyTransactionStorage

    Thread-safe storage of transactions.



    @@ -22,11 +22,16 @@ overwritten.

    + + +

    Inherited Functions

    + + +getTransaction diff --git a/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/index.html b/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/index.html new file mode 100644 index 0000000000..afdc8ad5bd --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/index.html @@ -0,0 +1,72 @@ + + +TxWritableStorageService - + + + +com.r3corda.core.node.services / TxWritableStorageService
    +
    +

    TxWritableStorageService

    +interface TxWritableStorageService : StorageService
    +

    Storage service, with extensions to allow validated transactions to be added to. For use only within ServiceHub.

    +
    +
    +

    Properties

    +
    -getTransaction -abstract fun getTransaction(id: SecureHash): SignedTransaction?

    Return the transaction with the given id, or null if no such transaction exists.

    +abstract fun getTransaction(id: SecureHash): SignedTransaction?

    Return the transaction with the given id, or null if no such transaction exists.

    + + + + + + +
    +validatedTransactions +abstract val validatedTransactions: TransactionStorage

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. +The signatures arent technically needed after that point, but we keep them around so that we can relay +the transaction data to other nodes that need it.

    +
    +

    Inherited Properties

    + + + + + + + + + + + + + + + +
    +attachments +abstract val attachments: AttachmentStorage

    Provides access to storage of arbitrary JAR files (which may contain only data, no code).

    +
    +myLegalIdentity +abstract val myLegalIdentity: Party

    Returns the legal identity that this node is configured with. Assumed to be initialised when the node is +first installed.

    +
    +myLegalIdentityKey +abstract val myLegalIdentityKey: KeyPair
    +

    Inheritors

    + + + + + + + + + + + +
    +MockStorageService +class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService
    +StorageServiceImpl +open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/validated-transactions.html b/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/validated-transactions.html new file mode 100644 index 0000000000..5e2ecae0c3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-tx-writable-storage-service/validated-transactions.html @@ -0,0 +1,19 @@ + + +TxWritableStorageService.validatedTransactions - + + + +com.r3corda.core.node.services / TxWritableStorageService / validatedTransactions
    +
    +

    validatedTransactions

    + +abstract val validatedTransactions: TransactionStorage
    +Overrides StorageService.validatedTransactions
    +

    A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. +The signatures arent technically needed after that point, but we keep them around so that we can relay +the transaction data to other nodes that need it.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/commit.html b/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/commit.html index 9a37fd6072..e52620df81 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/commit.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/commit.html @@ -7,8 +7,8 @@ com.r3corda.core.node.services / UniquenessProvider / commit

    commit

    - -abstract fun commit(tx: WireTransaction, callerIdentity: Party): Unit
    + +abstract fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit

    Commits all input states of the given transaction



    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/index.html b/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/index.html index b0659ef567..a76462c1ab 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-uniqueness-provider/index.html @@ -39,7 +39,7 @@ the caller identity requesting the commit

    commit -abstract fun commit(tx: WireTransaction, callerIdentity: Party): Unit

    Commits all input states of the given transaction

    +abstract fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit

    Commits all input states of the given transaction

    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/index.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/index.html index 68504524cf..34505ae7e1 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/index.html @@ -19,14 +19,6 @@ consumed by someone else first

    -cashBalances - -abstract val cashBalances: Map<Currency, Amount<Currency>>

    Returns a snapshot of how much cash we have in each currency, ignoring details like issuer. Note: currencies for -which we have no cash evaluate to null, not 0.

    - - - - currentWallet abstract val currentWallet: Wallet

    Returns a read-only snapshot of the wallet at the time the call is made. Note that if you consume states or @@ -79,7 +71,14 @@ new states that they create. You should only insert transactions that have been statesForRefs -open fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?> +open fun statesForRefs(refs: List<StateRef>): Map<StateRef, TransactionState<*>?> + + + +whenConsumed + +open fun whenConsumed(ref: StateRef): <ERROR CLASS><Update>

    Provide a Future for when a StateRef is consumed, which can be very useful in building tests.

    + @@ -99,9 +98,9 @@ new states that they create. You should only insert transactions that have been -NodeWalletService +InMemoryWalletService -class NodeWalletService : SingletonSerializeAsToken, WalletService

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +open class InMemoryWalletService : SingletonSerializeAsToken, WalletService

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/states-for-refs.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/states-for-refs.html index 879e850f2a..455112fee1 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/states-for-refs.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/states-for-refs.html @@ -8,7 +8,7 @@

    statesForRefs

    -open fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?>
    +open fun statesForRefs(refs: List<StateRef>): Map<StateRef, TransactionState<*>?>


    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/when-consumed.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/when-consumed.html new file mode 100644 index 0000000000..60012714d5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet-service/when-consumed.html @@ -0,0 +1,16 @@ + + +WalletService.whenConsumed - + + + +com.r3corda.core.node.services / WalletService / whenConsumed
    +
    +

    whenConsumed

    + +open fun whenConsumed(ref: StateRef): <ERROR CLASS><Update>
    +

    Provide a Future for when a StateRef is consumed, which can be very useful in building tests.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet/-init-.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet/-init-.html index b677b4c24c..132d9e3ea2 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-wallet/-init-.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet/-init-.html @@ -7,12 +7,15 @@ com.r3corda.core.node.services / Wallet / <init>

    <init>

    -Wallet()
    +Wallet(states: List<StateAndRef<ContractState>>)

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to change out from underneath you, even though the canonical currently-best-known wallet may change as we learn about new transactions from our peers and generate new transactions that consume states ourselves.

    -

    This absract class has no references to Cash contracts.

    +

    This abstract class has no references to Cash contracts.

    +

    states Holds the list of states that are active and relevant. +Active means they havent been consumed yet (or we dont know about it). +Relevant means they contain at least one of our pubkeys




    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet/index.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet/index.html index ffca4a47e5..eb3084d5cb 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-wallet/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet/index.html @@ -7,12 +7,15 @@ com.r3corda.core.node.services / Wallet

    Wallet

    -abstract class Wallet
    +class Wallet

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to change out from underneath you, even though the canonical currently-best-known wallet may change as we learn about new transactions from our peers and generate new transactions that consume states ourselves.

    -

    This absract class has no references to Cash contracts.

    +

    This abstract class has no references to Cash contracts.

    +

    states Holds the list of states that are active and relevant. +Active means they havent been consumed yet (or we dont know about it). +Relevant means they contain at least one of our pubkeys




    @@ -38,7 +41,7 @@ or transactions observed and the Wallet.

    <init> -Wallet()

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, +Wallet(states: List<StateAndRef<ContractState>>)

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to change out from underneath you, even though the canonical currently-best-known wallet may change as we learn about new transactions from our peers and generate new transactions that consume states ourselves.

    @@ -51,17 +54,9 @@ about new transactions from our peers and generate new transactions that consume -cashBalances - -abstract val cashBalances: Map<Currency, Amount<Currency>>

    Returns a map of how much cash we have in each currency, ignoring details like issuer. Note: currencies for -which we have no cash evaluate to null (not present in map), not 0.

    - - - - states -abstract val states: List<StateAndRef<ContractState>> +val states: List<StateAndRef<ContractState>> @@ -87,20 +82,29 @@ which we have no cash evaluate to null (not present in map), not 0.

    -

    Inheritors

    +

    Extension Properties

    +cashBalances
    -WalletImpl -class WalletImpl : Wallet

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, -because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to -change out from underneath you, even though the canonical currently-best-known wallet may change as we learn -about new transactions from our peers and generate new transactions that consume states ourselves.

    +val Wallet.cashBalances: Map<Currency, Amount<Currency>>

    Returns a map of how much cash we have in each currency, ignoring details like issuer. Note: currencies for +which we have no cash evaluate to null (not present in map), not 0.

    +

    Companion Object Extension Properties

    + + + + + + + +
    +clashingThreads +val Wallet.clashingThreads: Set<SecureHash>
    diff --git a/docs/build/html/api/com.r3corda.core.node.services/-wallet/states.html b/docs/build/html/api/com.r3corda.core.node.services/-wallet/states.html index a7759e18b8..00e945e833 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-wallet/states.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-wallet/states.html @@ -8,7 +8,7 @@

    states

    -abstract val states: List<StateAndRef<ContractState>>
    +val states: List<StateAndRef<ContractState>>


    diff --git a/docs/build/html/api/com.r3corda.core.node.services/index.html b/docs/build/html/api/com.r3corda.core.node.services/index.html index 50447bd74b..1731fddb92 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/index.html @@ -14,8 +14,7 @@ AttachmentStorage -interface AttachmentStorage

    An attachment store records potentially large binary objects, identified by their hash. Note that attachments are -immutable and can never be erased once inserted

    +interface AttachmentStorage

    An attachment store records potentially large binary objects, identified by their hash.

    @@ -47,6 +46,21 @@ with a specified network map service, which it fetches data from and then subscr +ReadOnlyTransactionStorage + +interface ReadOnlyTransactionStorage

    Thread-safe storage of transactions.

    + + + + +SchedulerService + +interface SchedulerService

    Provides access to schedule activity at some point in time. This interface might well be expanded to +increase the feature set in the future.

    + + + + ServiceType abstract class ServiceType

    Identifier for service types a node can expose over the network to other peers. These types are placed into network @@ -74,7 +88,14 @@ anything like that, this interface is only big enough to support the prototyping TransactionStorage -interface TransactionStorage

    Thread-safe storage of transactions.

    +interface TransactionStorage : ReadOnlyTransactionStorage

    Thread-safe storage of transactions.

    + + + + +TxWritableStorageService + +interface TxWritableStorageService : StorageService

    Storage service, with extensions to allow validated transactions to be added to. For use only within ServiceHub.

    @@ -89,7 +110,7 @@ if any of the inputs have already been used in another transaction

    Wallet -abstract class Wallet

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, +class Wallet

    A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to change out from underneath you, even though the canonical currently-best-known wallet may change as we learn about new transactions from our peers and generate new transactions that consume states ourselves.

    diff --git a/docs/build/html/api/com.r3corda.core.node/-service-hub/index.html b/docs/build/html/api/com.r3corda.core.node/-service-hub/index.html index 80d113581d..51888af6c6 100644 --- a/docs/build/html/api/com.r3corda.core.node/-service-hub/index.html +++ b/docs/build/html/api/com.r3corda.core.node/-service-hub/index.html @@ -52,6 +52,12 @@ state from being serialized in checkpoints.

    +schedulerService + +abstract val schedulerService: SchedulerService + + + storageService abstract val storageService: StorageService @@ -71,14 +77,16 @@ state from being serialized in checkpoints.

    loadState -open fun loadState(stateRef: StateRef): ContractState

    Given a StateRef loads the referenced transaction and looks up the specified output ContractState

    +open fun loadState(stateRef: StateRef): TransactionState<*>

    Given a StateRef loads the referenced transaction and looks up the specified output ContractState

    recordTransactions -open fun recordTransactions(txs: List<SignedTransaction>): Unit

    Given a list of SignedTransactions, writes them to the local storage for validated transactions and then +abstract fun recordTransactions(txs: Iterable<SignedTransaction>): Unit

    Given a list of SignedTransactions, writes them to the local storage for validated transactions and then +sends them to the wallet for further processing.

    +open fun recordTransactions(vararg txs: SignedTransaction): <ERROR CLASS>

    Given some SignedTransactions, writes them to the local storage for validated transactions and then sends them to the wallet for further processing.

    @@ -93,6 +101,19 @@ transaction. If no exception is thrown, the transaction is valid.

    +

    Extension Functions

    + + + + + + + +
    +fillWithSomeTestCash +fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>, notary: Party = DUMMY_NOTARY, atLeastThisManyStates: Int = 3, atMostThisManyStates: Int = 10, rng: Random = Random(), ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 0 }))): Wallet

    Creates a random set of between (by default) 3 and 10 cash states that add up to the given amount and adds them +to the wallet. This is intended for unit tests.

    +

    Inheritors

    @@ -100,7 +121,7 @@ transaction. If no exception is thrown, the transaction is valid.

    +abstract class ServiceHubInternal : ServiceHub
    ServiceHubInternal -interface ServiceHubInternal : ServiceHub
    diff --git a/docs/build/html/api/com.r3corda.core.node/-service-hub/load-state.html b/docs/build/html/api/com.r3corda.core.node/-service-hub/load-state.html index 9ea5448d29..72652b2df8 100644 --- a/docs/build/html/api/com.r3corda.core.node/-service-hub/load-state.html +++ b/docs/build/html/api/com.r3corda.core.node/-service-hub/load-state.html @@ -8,7 +8,7 @@

    loadState

    -open fun loadState(stateRef: StateRef): ContractState
    +open fun loadState(stateRef: StateRef): TransactionState<*>

    Given a StateRef loads the referenced transaction and looks up the specified output ContractState

    Exceptions

    diff --git a/docs/build/html/api/com.r3corda.core.node/-service-hub/record-transactions.html b/docs/build/html/api/com.r3corda.core.node/-service-hub/record-transactions.html index 0b1b605ee6..70b19b6fa5 100644 --- a/docs/build/html/api/com.r3corda.core.node/-service-hub/record-transactions.html +++ b/docs/build/html/api/com.r3corda.core.node/-service-hub/record-transactions.html @@ -7,13 +7,19 @@ com.r3corda.core.node / ServiceHub / recordTransactions

    recordTransactions

    - -open fun recordTransactions(txs: List<SignedTransaction>): Unit
    + +abstract fun recordTransactions(txs: Iterable<SignedTransaction>): Unit

    Given a list of SignedTransactions, 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.

    +

    Parameters

    + +txs - The transactions to record


    + +open fun recordTransactions(vararg txs: SignedTransaction): <ERROR CLASS>
    +

    Given some SignedTransactions, writes them to the local storage for validated transactions and then +sends them to the wallet for further processing.

    Parameters

    txs - The transactions to record
    diff --git a/docs/build/html/api/com.r3corda.core.node/-service-hub/scheduler-service.html b/docs/build/html/api/com.r3corda.core.node/-service-hub/scheduler-service.html new file mode 100644 index 0000000000..8c1d545883 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node/-service-hub/scheduler-service.html @@ -0,0 +1,15 @@ + + +ServiceHub.schedulerService - + + + +com.r3corda.core.node / ServiceHub / schedulerService
    +
    +

    schedulerService

    + +abstract val schedulerService: SchedulerService
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-app-context/-init-.html b/docs/build/html/api/com.r3corda.core.protocols/-app-context/-init-.html new file mode 100644 index 0000000000..7f3939f4b5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-app-context/-init-.html @@ -0,0 +1,16 @@ + + +AppContext.<init> - + + + +com.r3corda.core.protocols / AppContext / <init>
    +
    +

    <init>

    +AppContext(attachments: List<SecureHash>)
    +

    This is just some way to track what attachments need to be in the class loader, but may later include some app +properties loaded from the attachments. And perhaps the authenticated user for an API call?

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-app-context/attachments.html b/docs/build/html/api/com.r3corda.core.protocols/-app-context/attachments.html new file mode 100644 index 0000000000..4c8bde1693 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-app-context/attachments.html @@ -0,0 +1,15 @@ + + +AppContext.attachments - + + + +com.r3corda.core.protocols / AppContext / attachments
    +
    +

    attachments

    + +val attachments: List<SecureHash>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-app-context/class-loader.html b/docs/build/html/api/com.r3corda.core.protocols/-app-context/class-loader.html new file mode 100644 index 0000000000..d3da155f97 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-app-context/class-loader.html @@ -0,0 +1,15 @@ + + +AppContext.classLoader - + + + +com.r3corda.core.protocols / AppContext / classLoader
    +
    +

    classLoader

    + +val classLoader: ClassLoader
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-app-context/index.html b/docs/build/html/api/com.r3corda.core.protocols/-app-context/index.html new file mode 100644 index 0000000000..4ceb94f3e3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-app-context/index.html @@ -0,0 +1,46 @@ + + +AppContext - + + + +com.r3corda.core.protocols / AppContext
    +
    +

    AppContext

    +data class AppContext
    +

    This is just some way to track what attachments need to be in the class loader, but may later include some app +properties loaded from the attachments. And perhaps the authenticated user for an API call?

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +AppContext(attachments: List<SecureHash>)

    This is just some way to track what attachments need to be in the class loader, but may later include some app +properties loaded from the attachments. And perhaps the authenticated user for an API call?

    +
    +

    Properties

    + + + + + + + + + + + +
    +attachments +val attachments: List<SecureHash>
    +classLoader +val classLoader: ClassLoader
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/-init-.html b/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/-init-.html new file mode 100644 index 0000000000..3b3ce12894 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/-init-.html @@ -0,0 +1,14 @@ + + +IllegalProtocolLogicException.<init> - + + + +com.r3corda.core.protocols / IllegalProtocolLogicException / <init>
    +
    +

    <init>

    +IllegalProtocolLogicException(type: Class<*>, msg: String)
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/index.html b/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/index.html new file mode 100644 index 0000000000..daccd9c4d8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-illegal-protocol-logic-exception/index.html @@ -0,0 +1,25 @@ + + +IllegalProtocolLogicException - + + + +com.r3corda.core.protocols / IllegalProtocolLogicException
    +
    +

    IllegalProtocolLogicException

    +class IllegalProtocolLogicException : IllegalArgumentException
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +IllegalProtocolLogicException(type: Class<*>, msg: String)
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/-init-.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/-init-.html new file mode 100644 index 0000000000..c2e8360e32 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/-init-.html @@ -0,0 +1,26 @@ + + +ProtocolLogicRefFactory.<init> - + + + +com.r3corda.core.protocols / ProtocolLogicRefFactory / <init>
    +
    +

    <init>

    +ProtocolLogicRefFactory()
    +
    +
    +ProtocolLogicRefFactory(protocolLogicClassNameWhitelist: Set<String>, argsClassNameWhitelist: Set<String>)
    +

    A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

    +

    Validation of types is performed on the way in and way out in case this object is passed between JVMs which might have differing +whitelists.

    +

    TODO: Ways to populate whitelist of "blessed" protocols per node/party +TODO: Ways to populate argument types whitelist. Per node/party or global? +TODO: Align with API related logic for passing in ProtocolLogic references (ProtocolRef) +TODO: Actual support for AppContext / AttachmentsClassLoader

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create-kotlin.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create-kotlin.html new file mode 100644 index 0000000000..bcdf3e2429 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create-kotlin.html @@ -0,0 +1,19 @@ + + +ProtocolLogicRefFactory.createKotlin - + + + +com.r3corda.core.protocols / ProtocolLogicRefFactory / createKotlin
    +
    +

    createKotlin

    + +fun createKotlin(type: Class<out ProtocolLogic<*>>, args: Map<String, Any?>): ProtocolLogicRef
    +

    Create a ProtocolLogicRef by trying to find a Kotlin constructor that matches the given args.

    +

    TODO: Rethink language specific naming.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create.html new file mode 100644 index 0000000000..bfef9758d2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/create.html @@ -0,0 +1,16 @@ + + +ProtocolLogicRefFactory.create - + + + +com.r3corda.core.protocols / ProtocolLogicRefFactory / create
    +
    +

    create

    + +fun create(type: Class<out ProtocolLogic<*>>, vararg args: Any?): ProtocolLogicRef
    +

    Create a ProtocolLogicRef for the Kotlin primary constructor or Java constructor and the given args.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/index.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/index.html new file mode 100644 index 0000000000..f14b826acf --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/index.html @@ -0,0 +1,71 @@ + + +ProtocolLogicRefFactory - + + + +com.r3corda.core.protocols / ProtocolLogicRefFactory
    +
    +

    ProtocolLogicRefFactory

    +class ProtocolLogicRefFactory : SingletonSerializeAsToken
    +

    A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

    +

    Validation of types is performed on the way in and way out in case this object is passed between JVMs which might have differing +whitelists.

    +

    TODO: Ways to populate whitelist of "blessed" protocols per node/party +TODO: Ways to populate argument types whitelist. Per node/party or global? +TODO: Align with API related logic for passing in ProtocolLogic references (ProtocolRef) +TODO: Actual support for AppContext / AttachmentsClassLoader

    +
    +
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +ProtocolLogicRefFactory()ProtocolLogicRefFactory(protocolLogicClassNameWhitelist: Set<String>, argsClassNameWhitelist: Set<String>)

    A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

    +
    +

    Functions

    + + + + + + + + + + + + + + + +
    +create +fun create(type: Class<out ProtocolLogic<*>>, vararg args: Any?): ProtocolLogicRef

    Create a ProtocolLogicRef for the Kotlin primary constructor or Java constructor and the given args.

    +
    +createKotlin +fun createKotlin(type: Class<out ProtocolLogic<*>>, args: Map<String, Any?>): ProtocolLogicRef

    Create a ProtocolLogicRef by trying to find a Kotlin constructor that matches the given args.

    +
    +toProtocolLogic +fun toProtocolLogic(ref: ProtocolLogicRef): ProtocolLogic<*>
    +

    Inherited Functions

    + + + + + + + +
    +toToken +open fun toToken(context: SerializeAsTokenContext): SerializationToken
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/to-protocol-logic.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/to-protocol-logic.html new file mode 100644 index 0000000000..22cad2ce08 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref-factory/to-protocol-logic.html @@ -0,0 +1,15 @@ + + +ProtocolLogicRefFactory.toProtocolLogic - + + + +com.r3corda.core.protocols / ProtocolLogicRefFactory / toProtocolLogic
    +
    +

    toProtocolLogic

    + +fun toProtocolLogic(ref: ProtocolLogicRef): ProtocolLogic<*>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/app-context.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/app-context.html new file mode 100644 index 0000000000..5feed5296a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/app-context.html @@ -0,0 +1,15 @@ + + +ProtocolLogicRef.appContext - + + + +com.r3corda.core.protocols / ProtocolLogicRef / appContext
    +
    +

    appContext

    + +val appContext: AppContext
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/args.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/args.html new file mode 100644 index 0000000000..8610f882a1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/args.html @@ -0,0 +1,15 @@ + + +ProtocolLogicRef.args - + + + +com.r3corda.core.protocols / ProtocolLogicRef / args
    +
    +

    args

    + +val args: Map<String, Any?>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/index.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/index.html new file mode 100644 index 0000000000..570352d5d2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/index.html @@ -0,0 +1,41 @@ + + +ProtocolLogicRef - + + + +com.r3corda.core.protocols / ProtocolLogicRef
    +
    +

    ProtocolLogicRef

    +data class ProtocolLogicRef
    +

    A class representing a ProtocolLogic instance which would be possible to safely pass out of the contract sandbox

    +

    Only allows a String reference to the ProtocolLogic class, and only allows restricted argument types as per ProtocolLogicRefFactory

    +
    +
    +
    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +appContext +val appContext: AppContext
    +args +val args: Map<String, Any?>
    +protocolLogicClassName +val protocolLogicClassName: String
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/protocol-logic-class-name.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/protocol-logic-class-name.html new file mode 100644 index 0000000000..9cc5eb55ca --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic-ref/protocol-logic-class-name.html @@ -0,0 +1,15 @@ + + +ProtocolLogicRef.protocolLogicClassName - + + + +com.r3corda.core.protocols / ProtocolLogicRef / protocolLogicClassName
    +
    +

    protocolLogicClassName

    + +val protocolLogicClassName: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/index.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/index.html index 25dd4ce6d3..3ad85c9833 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/index.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/index.html @@ -69,7 +69,9 @@ progress.

    serviceHub -val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

    +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    @@ -95,13 +97,13 @@ progress.

    send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> @@ -118,6 +120,12 @@ progress.

    +Acceptor + +abstract class Acceptor<T> : ProtocolLogic<Unit> + + + Broadcast class Broadcast : ProtocolLogic<Boolean>

    This takes a Java Integer rather than Kotlin Int as that is what we end up with in the calling map and currently @@ -128,7 +136,7 @@ we do not support coercing numeric types in the reflective search for matching c Broadcast -class Broadcast : ProtocolLogic<Boolean> +class Broadcast : ProtocolLogic<Unit> @@ -153,6 +161,19 @@ timestamp is correct and none of its inputs have been used in another completed +FixingRoleDecider + +class FixingRoleDecider : ProtocolLogic<Unit>

    This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing.

    + + + + +Instigator + +abstract class Instigator<S : ContractState, T> : ProtocolLogic<StateAndRef<S>> + + + Primary abstract class Primary<U> : ProtocolLogic<SignedTransaction>

    Abstracted bilateral deal protocol participant that initiates communication/handshake.

    @@ -172,7 +193,7 @@ for each step.

    Requester -class Requester<T> : ProtocolLogic<SignedTransaction> +class Requester : ProtocolLogic<SignedTransaction> @@ -204,24 +225,6 @@ all the transactions have been successfully verified and inserted into the local if any of the input states have been previously committed.

    - - -TraderDemoProtocolBuyer - -class TraderDemoProtocolBuyer : ProtocolLogic<Unit> - - - -TraderDemoProtocolSeller - -class TraderDemoProtocolSeller : ProtocolLogic<Unit> - - - -Updater - -class Updater : ProtocolLogic<Boolean> - diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send-and-receive.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send-and-receive.html index d04c258dac..8e1c8b402d 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send-and-receive.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send-and-receive.html @@ -7,8 +7,8 @@ com.r3corda.core.protocols / ProtocolLogic / sendAndReceive

    sendAndReceive

    - -inline fun <reified T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T>
    + +inline fun <reified T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T>


    diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send.html index 18cbc9cbab..be065bd959 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/send.html @@ -7,8 +7,8 @@ com.r3corda.core.protocols / ProtocolLogic / send

    send

    - -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit
    + +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit


    diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/service-hub.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/service-hub.html index 732a0c9098..cfecaade40 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/service-hub.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-logic/service-hub.html @@ -9,7 +9,9 @@

    serviceHub

    val serviceHub: ServiceHub
    -

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

    +

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.



    diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/index.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/index.html index e6cdd513ca..68c1b25b10 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/index.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/index.html @@ -41,13 +41,13 @@ send -abstract fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +abstract fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -abstract fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any, recvType: Class<T>): UntrustworthyData<T> +abstract fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send-and-receive.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send-and-receive.html index f0a652fe04..1977e31a8a 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send-and-receive.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send-and-receive.html @@ -7,8 +7,8 @@ com.r3corda.core.protocols / ProtocolStateMachine / sendAndReceive

    sendAndReceive

    - -abstract fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any, recvType: Class<T>): UntrustworthyData<T>
    + +abstract fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T>


    diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send.html index 0b35e7f501..9f38e34e50 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send.html +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/send.html @@ -7,8 +7,8 @@ com.r3corda.core.protocols / ProtocolStateMachine / send

    send

    - -abstract fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit
    + +abstract fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit


    diff --git a/docs/build/html/api/com.r3corda.core.protocols/index.html b/docs/build/html/api/com.r3corda.core.protocols/index.html index 0b1a935fa1..4bc918e6fc 100644 --- a/docs/build/html/api/com.r3corda.core.protocols/index.html +++ b/docs/build/html/api/com.r3corda.core.protocols/index.html @@ -12,6 +12,14 @@ +AppContext + +data class AppContext

    This is just some way to track what attachments need to be in the class loader, but may later include some app +properties loaded from the attachments. And perhaps the authenticated user for an API call?

    + + + + ProtocolLogic abstract class ProtocolLogic<T>

    A sub-class of ProtocolLogic implements a protocol flow using direct, straight line blocking code. Thus you @@ -21,6 +29,20 @@ a node crash, how many instances of your protocol there are running and so on. +ProtocolLogicRef + +data class ProtocolLogicRef

    A class representing a ProtocolLogic instance which would be possible to safely pass out of the contract sandbox

    + + + + +ProtocolLogicRefFactory + +class ProtocolLogicRefFactory : SingletonSerializeAsToken

    A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

    + + + + ProtocolStateMachine interface ProtocolStateMachine<R>

    The interface of ProtocolStateMachineImpl exposing methods and properties required by ProtocolLogic for compilation

    @@ -28,5 +50,16 @@ a node crash, how many instances of your protocol there are running and so on. +

    Exceptions

    + + + + + + + +
    +IllegalProtocolLogicException +class IllegalProtocolLogicException : IllegalArgumentException
    diff --git a/docs/build/html/api/com.r3corda.core.serialization/-deserialize-as-kotlin-object-def.html b/docs/build/html/api/com.r3corda.core.serialization/-deserialize-as-kotlin-object-def.html new file mode 100644 index 0000000000..1d2fb41a74 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-deserialize-as-kotlin-object-def.html @@ -0,0 +1,28 @@ + + +DeserializeAsKotlinObjectDef - + + + +com.r3corda.core.serialization / DeserializeAsKotlinObjectDef
    +
    +

    DeserializeAsKotlinObjectDef

    +interface DeserializeAsKotlinObjectDef
    +

    Marker interface for kotlin object definitions so that they are deserialized as the singleton instance.

    +
    +
    +

    Inheritors

    + + + + + + + +
    +Ack +object Ack : DeserializeAsKotlinObjectDef

    A general Ack message that conveys no content other than its presence for use when you want an acknowledgement +from a recipient. Using Unit can be ambiguous as it is similar to Void and so could mean no response.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/ed25519-curve.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/ed25519-curve.html new file mode 100644 index 0000000000..cdf43d0e49 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/ed25519-curve.html @@ -0,0 +1,15 @@ + + +Ed25519PrivateKeySerializer.ed25519Curve - + + + +com.r3corda.core.serialization / Ed25519PrivateKeySerializer / ed25519Curve
    +
    +

    ed25519Curve

    + +val ed25519Curve: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/index.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/index.html new file mode 100644 index 0000000000..d79a256142 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/index.html @@ -0,0 +1,43 @@ + + +Ed25519PrivateKeySerializer - + + + +com.r3corda.core.serialization / Ed25519PrivateKeySerializer
    +
    +

    Ed25519PrivateKeySerializer

    +object Ed25519PrivateKeySerializer
    +

    For serialising an ed25519 private key

    +
    +
    +

    Properties

    + + + + + + + +
    +ed25519Curve +val ed25519Curve: <ERROR CLASS>
    +

    Functions

    + + + + + + + + + + + +
    +read +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<<ERROR CLASS>>): <ERROR CLASS>
    +write +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: <ERROR CLASS>): Unit
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/read.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/read.html new file mode 100644 index 0000000000..20b106d766 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/read.html @@ -0,0 +1,15 @@ + + +Ed25519PrivateKeySerializer.read - + + + +com.r3corda.core.serialization / Ed25519PrivateKeySerializer / read
    +
    +

    read

    + +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<<ERROR CLASS>>): <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/write.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/write.html new file mode 100644 index 0000000000..507b1a88b5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-private-key-serializer/write.html @@ -0,0 +1,15 @@ + + +Ed25519PrivateKeySerializer.write - + + + +com.r3corda.core.serialization / Ed25519PrivateKeySerializer / write
    +
    +

    write

    + +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: <ERROR CLASS>): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/ed25519-curve.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/ed25519-curve.html new file mode 100644 index 0000000000..45242ffe71 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/ed25519-curve.html @@ -0,0 +1,15 @@ + + +Ed25519PublicKeySerializer.ed25519Curve - + + + +com.r3corda.core.serialization / Ed25519PublicKeySerializer / ed25519Curve
    +
    +

    ed25519Curve

    + +val ed25519Curve: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/index.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/index.html new file mode 100644 index 0000000000..f99f8480a9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/index.html @@ -0,0 +1,43 @@ + + +Ed25519PublicKeySerializer - + + + +com.r3corda.core.serialization / Ed25519PublicKeySerializer
    +
    +

    Ed25519PublicKeySerializer

    +object Ed25519PublicKeySerializer
    +

    For serialising an ed25519 public key

    +
    +
    +

    Properties

    + + + + + + + +
    +ed25519Curve +val ed25519Curve: <ERROR CLASS>
    +

    Functions

    + + + + + + + + + + + +
    +read +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<<ERROR CLASS>>): <ERROR CLASS>
    +write +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: <ERROR CLASS>): Unit
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/read.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/read.html new file mode 100644 index 0000000000..df058dc263 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/read.html @@ -0,0 +1,15 @@ + + +Ed25519PublicKeySerializer.read - + + + +com.r3corda.core.serialization / Ed25519PublicKeySerializer / read
    +
    +

    read

    + +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<<ERROR CLASS>>): <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/write.html b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/write.html new file mode 100644 index 0000000000..65743cb547 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-ed25519-public-key-serializer/write.html @@ -0,0 +1,15 @@ + + +Ed25519PublicKeySerializer.write - + + + +com.r3corda.core.serialization / Ed25519PublicKeySerializer / write
    +
    +

    write

    + +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: <ERROR CLASS>): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/index.html b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/index.html new file mode 100644 index 0000000000..cb338eb85d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/index.html @@ -0,0 +1,32 @@ + + +KotlinObjectSerializer - + + + +com.r3corda.core.serialization / KotlinObjectSerializer
    +
    +

    KotlinObjectSerializer

    +object KotlinObjectSerializer
    +

    Serializer to deserialize kotlin object definitions marked with DeserializeAsKotlinObjectDef.

    +
    +
    +

    Functions

    + + + + + + + + + + + +
    +read +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<DeserializeAsKotlinObjectDef>): DeserializeAsKotlinObjectDef
    +write +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: DeserializeAsKotlinObjectDef): Unit
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/read.html b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/read.html new file mode 100644 index 0000000000..00c090e9ab --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/read.html @@ -0,0 +1,15 @@ + + +KotlinObjectSerializer.read - + + + +com.r3corda.core.serialization / KotlinObjectSerializer / read
    +
    +

    read

    + +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<DeserializeAsKotlinObjectDef>): DeserializeAsKotlinObjectDef
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/write.html b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/write.html new file mode 100644 index 0000000000..995662f981 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/-kotlin-object-serializer/write.html @@ -0,0 +1,15 @@ + + +KotlinObjectSerializer.write - + + + +com.r3corda.core.serialization / KotlinObjectSerializer / write
    +
    +

    write

    + +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: DeserializeAsKotlinObjectDef): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-serialize-as-token/index.html b/docs/build/html/api/com.r3corda.core.serialization/-serialize-as-token/index.html index ccd7d2d4e3..c00132293c 100644 --- a/docs/build/html/api/com.r3corda.core.serialization/-serialize-as-token/index.html +++ b/docs/build/html/api/com.r3corda.core.serialization/-serialize-as-token/index.html @@ -51,6 +51,13 @@ they are serialized because they have a lot of internal state that does not seri to indicate which instance the token is a serialized form of.

    + + +TestClock + +class TestClock : MutableClock, SerializeAsToken

    A Clock that can have the time advanced for use in testing

    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/-singleton-serialize-as-token/index.html b/docs/build/html/api/com.r3corda.core.serialization/-singleton-serialize-as-token/index.html index 61af8bd89a..b7314a981d 100644 --- a/docs/build/html/api/com.r3corda.core.serialization/-singleton-serialize-as-token/index.html +++ b/docs/build/html/api/com.r3corda.core.serialization/-singleton-serialize-as-token/index.html @@ -41,6 +41,13 @@ to indicate which instance the token is a serialized form of.

    +AbstractNodeService + +abstract class AbstractNodeService : SingletonSerializeAsToken

    Abstract superclass for services that a node can host, which provides helper functions.

    + + + + ArtemisMessagingService class ArtemisMessagingService : SingletonSerializeAsToken, MessagingService

    This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product. @@ -92,6 +99,15 @@ testing).

    +InMemoryWalletService + +open class InMemoryWalletService : SingletonSerializeAsToken, WalletService

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    + + + + MockIdentityService class MockIdentityService : IdentityService, SingletonSerializeAsToken @@ -106,7 +122,7 @@ testing).

    MockStorageService -class MockStorageService : SingletonSerializeAsToken, StorageService +class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService @@ -118,18 +134,24 @@ This is not an interface because it is too lightweight to bother mocking out.

    -NodeWalletService +NodeSchedulerService -class NodeWalletService : SingletonSerializeAsToken, WalletService

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    +class NodeSchedulerService : SchedulerService, SingletonSerializeAsToken

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    + + + + +ProtocolLogicRefFactory + +class ProtocolLogicRefFactory : SingletonSerializeAsToken

    A class for conversion to and from ProtocolLogic and ProtocolLogicRef instances

    StorageServiceImpl -open class StorageServiceImpl : SingletonSerializeAsToken, StorageService +open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService diff --git a/docs/build/html/api/com.r3corda.core.serialization/index.html b/docs/build/html/api/com.r3corda.core.serialization/index.html index 1d88104185..eb33e0e054 100644 --- a/docs/build/html/api/com.r3corda.core.serialization/index.html +++ b/docs/build/html/api/com.r3corda.core.serialization/index.html @@ -12,6 +12,27 @@ +DeserializeAsKotlinObjectDef + +interface DeserializeAsKotlinObjectDef

    Marker interface for kotlin object definitions so that they are deserialized as the singleton instance.

    + + + + +Ed25519PrivateKeySerializer + +object Ed25519PrivateKeySerializer

    For serialising an ed25519 private key

    + + + + +Ed25519PublicKeySerializer + +object Ed25519PublicKeySerializer

    For serialising an ed25519 public key

    + + + + ImmutableClassSerializer class ImmutableClassSerializer<T : Any>

    Serializes properties and deserializes by using the constructor. This assumes that all backed properties are @@ -20,6 +41,13 @@ set via the constructor and the class is immutable.

    +KotlinObjectSerializer + +object KotlinObjectSerializer

    Serializer to deserialize kotlin object definitions marked with DeserializeAsKotlinObjectDef.

    + + + + NoReferencesSerializer class NoReferencesSerializer<T> @@ -186,6 +214,12 @@ references will throw a stack overflow exception during serialisation.

    +readBytesWithLength + +fun <ERROR CLASS>.readBytesWithLength(): ByteArray + + + serialize fun <T : Any> T.serialize(kryo: <ERROR CLASS> = THREAD_LOCAL_KRYO.get()): SerializedBytes<T>

    Can be called on any object to convert it to a byte array (wrapped by SerializedBytes), regardless of whether @@ -198,6 +232,12 @@ the type is marked as serializable or was designed for it (so be careful)

    fun <T> <ERROR CLASS>.useClassLoader(cl: ClassLoader, body: () -> T): T + + +writeBytesWithLength + +fun <ERROR CLASS>.writeBytesWithLength(byteArray: ByteArray): Unit + diff --git a/docs/build/html/api/com.r3corda.core.serialization/read-bytes-with-length.html b/docs/build/html/api/com.r3corda.core.serialization/read-bytes-with-length.html new file mode 100644 index 0000000000..bf1c76cc3d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/read-bytes-with-length.html @@ -0,0 +1,15 @@ + + +readBytesWithLength - + + + +com.r3corda.core.serialization / readBytesWithLength
    +
    +

    readBytesWithLength

    + +fun <ERROR CLASS>.readBytesWithLength(): ByteArray
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.serialization/write-bytes-with-length.html b/docs/build/html/api/com.r3corda.core.serialization/write-bytes-with-length.html new file mode 100644 index 0000000000..8f4624d47b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.serialization/write-bytes-with-length.html @@ -0,0 +1,15 @@ + + +writeBytesWithLength - + + + +com.r3corda.core.serialization / writeBytesWithLength
    +
    +

    writeBytesWithLength

    + +fun <ERROR CLASS>.writeBytesWithLength(byteArray: ByteArray): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-a-l-l_-t-e-s-t_-k-e-y-s.html b/docs/build/html/api/com.r3corda.core.testing/-a-l-l_-t-e-s-t_-k-e-y-s.html index 9876213963..cfca05a6d5 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-a-l-l_-t-e-s-t_-k-e-y-s.html +++ b/docs/build/html/api/com.r3corda.core.testing/-a-l-l_-t-e-s-t_-k-e-y-s.html @@ -8,7 +8,7 @@

    ALL_TEST_KEYS

    -val ALL_TEST_KEYS: <ERROR CLASS>
    +val ALL_TEST_KEYS: List<KeyPair>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/add-command.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/add-command.html new file mode 100644 index 0000000000..7effd7ce84 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/add-command.html @@ -0,0 +1,15 @@ + + +AbstractTransactionForTest.addCommand - + + + +com.r3corda.core.testing / AbstractTransactionForTest / addCommand
    +
    +

    addCommand

    + +fun addCommand(cmd: Command): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/arg.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/arg.html index a179d38ef4..177006757d 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/arg.html +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/arg.html @@ -8,7 +8,9 @@

    arg

    -fun arg(vararg key: PublicKey, c: () -> CommandData): Unit
    +fun arg(vararg keys: PublicKey, c: () -> CommandData): Unit
    + +fun arg(key: PublicKey, c: CommandData): Unit


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/index.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/index.html index 6db2b65487..64c1715f22 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/index.html @@ -42,6 +42,18 @@ val outStates: ArrayList<LabeledOutput> + + +signers + +val signers: LinkedHashSet<PublicKey> + + + +type + +val type: General +

    Functions

    @@ -49,9 +61,16 @@ +addCommand + +fun addCommand(cmd: Command): Unit + + + arg -fun arg(vararg key: PublicKey, c: () -> CommandData): Unit +fun arg(vararg keys: PublicKey, c: () -> CommandData): Unit
    +fun arg(key: PublicKey, c: CommandData): Unit @@ -69,7 +88,8 @@ output -open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS> +open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS>
    +open fun output(label: String? = null, s: ContractState): <ERROR CLASS> @@ -82,7 +102,7 @@ transaction -fun transaction(body: TransactionForTest.() -> Unit): Unit +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): Unit diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/output.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/output.html index b8b7474a18..de698b043c 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/output.html +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/output.html @@ -9,6 +9,8 @@

    output

    open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS>
    + +open fun output(label: String? = null, s: ContractState): <ERROR CLASS>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/signers.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/signers.html new file mode 100644 index 0000000000..6e4aedb0c9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/signers.html @@ -0,0 +1,15 @@ + + +AbstractTransactionForTest.signers - + + + +com.r3corda.core.testing / AbstractTransactionForTest / signers
    +
    +

    signers

    + +protected val signers: LinkedHashSet<PublicKey>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/transaction.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/transaction.html index 8ccd4c8015..40923e52c0 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/transaction.html +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/transaction.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / AbstractTransactionForTest / transaction

    transaction

    - -fun transaction(body: TransactionForTest.() -> Unit): Unit
    + +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): Unit
    Deprecated: Cannot nest transactions, use tweak


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/type.html b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/type.html new file mode 100644 index 0000000000..2550d0e3c0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-abstract-transaction-for-test/type.html @@ -0,0 +1,15 @@ + + +AbstractTransactionForTest.type - + + + +com.r3corda.core.testing / AbstractTransactionForTest / type
    +
    +

    type

    + +protected val type: General
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/-init-.html b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/-init-.html new file mode 100644 index 0000000000..e34050e4e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/-init-.html @@ -0,0 +1,14 @@ + + +AlwaysSucceedContract.<init> - + + + +com.r3corda.core.testing / AlwaysSucceedContract / <init>
    +
    +

    <init>

    +AlwaysSucceedContract(legalContractReference: SecureHash = SecureHash.sha256("Always succeed contract"))
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/index.html b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/index.html new file mode 100644 index 0000000000..ea2c7e7570 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/index.html @@ -0,0 +1,53 @@ + + +AlwaysSucceedContract - + + + +com.r3corda.core.testing / AlwaysSucceedContract
    +
    +

    AlwaysSucceedContract

    +class AlwaysSucceedContract : Contract
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +AlwaysSucceedContract(legalContractReference: SecureHash = SecureHash.sha256("Always succeed contract"))
    +

    Properties

    + + + + + + + +
    +legalContractReference +val legalContractReference: SecureHash

    Unparsed reference to the natural language contract that this code is supposed to express (usually a hash of +the contracts contents).

    +
    +

    Functions

    + + + + + + + +
    +verify +fun verify(tx: TransactionForContract): Unit

    Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. +Must throw an exception if theres a problem that should prevent state transition. Takes a single object +rather than an argument so that additional data can be added without breaking binary compatibility with +existing contract code.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/legal-contract-reference.html b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/legal-contract-reference.html new file mode 100644 index 0000000000..38c44cf4ad --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/legal-contract-reference.html @@ -0,0 +1,18 @@ + + +AlwaysSucceedContract.legalContractReference - + + + +com.r3corda.core.testing / AlwaysSucceedContract / legalContractReference
    +
    +

    legalContractReference

    + +val legalContractReference: SecureHash
    +Overrides Contract.legalContractReference
    +

    Unparsed reference to the natural language contract that this code is supposed to express (usually a hash of +the contracts contents).

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/verify.html b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/verify.html new file mode 100644 index 0000000000..05c1367d5c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-always-succeed-contract/verify.html @@ -0,0 +1,20 @@ + + +AlwaysSucceedContract.verify - + + + +com.r3corda.core.testing / AlwaysSucceedContract / verify
    +
    +

    verify

    + +fun verify(tx: TransactionForContract): Unit
    +Overrides Contract.verify
    +

    Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. +Must throw an exception if theres a problem that should prevent state transition. Takes a single object +rather than an argument so that additional data can be added without breaking binary compatibility with +existing contract code.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_1.html b/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_1.html index cc4c410c59..0344fdfb15 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_1.html +++ b/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_1.html @@ -8,7 +8,7 @@

    DUMMY_PUBKEY_1

    -val DUMMY_PUBKEY_1: DummyPublicKey
    +val DUMMY_PUBKEY_1: PublicKey


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_2.html b/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_2.html index b7e7833b37..2f72d9c0c1 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_2.html +++ b/docs/build/html/api/com.r3corda.core.testing/-d-u-m-m-y_-p-u-b-k-e-y_2.html @@ -8,7 +8,7 @@

    DUMMY_PUBKEY_2

    -val DUMMY_PUBKEY_2: DummyPublicKey
    +val DUMMY_PUBKEY_2: PublicKey


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/-init-.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/-init-.html new file mode 100644 index 0000000000..34f9cffd86 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/-init-.html @@ -0,0 +1,14 @@ + + +DummyLinearState.<init> - + + + +com.r3corda.core.testing / DummyLinearState / <init>
    +
    +

    <init>

    +DummyLinearState(thread: SecureHash = SecureHash.randomSHA256(), contract: Contract = AlwaysSucceedContract(), participants: List<PublicKey> = listOf(), nonce: SecureHash = SecureHash.randomSHA256())
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/contract.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/contract.html new file mode 100644 index 0000000000..c86f9eefd6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/contract.html @@ -0,0 +1,43 @@ + + +DummyLinearState.contract - + + + +com.r3corda.core.testing / DummyLinearState / contract
    +
    +

    contract

    + +val contract: Contract
    +Overrides ContractState.contract
    +

    An instance of the contract class that will verify this state.

    +

    Discussion

    +

    This field is not the final design, its just a piece of temporary scaffolding. Once the contract sandbox is +further along, this field will become a description of which attachments are acceptable for defining the +contract.

    +

    Recall that an attachment is a zip file that can be referenced from any transaction. The contents of the +attachments are merged together and cannot define any overlapping files, thus for any given transaction there +is a miniature file system in which each file can be precisely mapped to the defining attachment.

    +

    Attachments may contain many things (data files, legal documents, etc) but mostly they contain JVM bytecode. +The class files inside define not only Contract implementations but also the classes that define the states. +Within the rest of a transaction, user-providable components are referenced by name only.

    +

    This means that a smart contract in Corda does two things:

    +
    1. Define the data structures that compose the ledger (the states)

      +
    2. Define the rules for updating those structures

      +

    The first is merely a utility role ... in theory contract code could manually parse byte streams by hand. +The second is vital to the integrity of the ledger. So this field needs to be able to express constraints like:

    +
    • Only attachment 733c350f396a727655be1363c06635ba355036bd54a5ed6e594fd0b5d05f42f6 may be used with this state.

      +
    • Any attachment signed by public key 2d1ce0e330c52b8055258d776c40 may be used with this state.

      +
    • Attachments (1, 2, 3) may all be used with this state.

      +

    and so on. In this way it becomes possible for the business logic governing a state to be evolved, if the +constraints are flexible enough.

    +

    Because contract classes often also define utilities that generate relevant transactions, and because attachments +cannot know their own hashes, we will have to provide various utilities to assist with obtaining the right +code constraints from within the contract code itself.

    +

    TODO: Implement the above description. See COR-226

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/index.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/index.html new file mode 100644 index 0000000000..79dbcfd2b2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/index.html @@ -0,0 +1,87 @@ + + +DummyLinearState - + + + +com.r3corda.core.testing / DummyLinearState
    +
    +

    DummyLinearState

    +class DummyLinearState : LinearState
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +DummyLinearState(thread: SecureHash = SecureHash.randomSHA256(), contract: Contract = AlwaysSucceedContract(), participants: List<PublicKey> = listOf(), nonce: SecureHash = SecureHash.randomSHA256())
    +

    Properties

    + + + + + + + + + + + + + + + + + + + +
    +contract +val contract: Contract

    An instance of the contract class that will verify this state.

    +
    +nonce +val nonce: SecureHash
    +participants +val participants: List<PublicKey>

    A participant is any party that is able to consume this state in a valid transaction.

    +
    +thread +val thread: SecureHash

    Unique thread id within the wallets of all parties

    +
    +

    Functions

    + + + + + + + +
    +isRelevant +fun isRelevant(ourKeys: Set<PublicKey>): Boolean

    true if this should be tracked by our wallet(s)

    +
    +

    Extension Functions

    + + + + + + + + + + + +
    +hash +fun ContractState.hash(): SecureHash

    Returns the SHA-256 hash of the serialised contents of this state (not cached)

    +
    +with notary +infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/is-relevant.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/is-relevant.html new file mode 100644 index 0000000000..cc20a0b156 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/is-relevant.html @@ -0,0 +1,17 @@ + + +DummyLinearState.isRelevant - + + + +com.r3corda.core.testing / DummyLinearState / isRelevant
    +
    +

    isRelevant

    + +fun isRelevant(ourKeys: Set<PublicKey>): Boolean
    +Overrides LinearState.isRelevant
    +

    true if this should be tracked by our wallet(s)

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/nonce.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/nonce.html new file mode 100644 index 0000000000..65100719da --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/nonce.html @@ -0,0 +1,15 @@ + + +DummyLinearState.nonce - + + + +com.r3corda.core.testing / DummyLinearState / nonce
    +
    +

    nonce

    + +val nonce: SecureHash
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/participants.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/participants.html new file mode 100644 index 0000000000..2c70d42cab --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/participants.html @@ -0,0 +1,25 @@ + + +DummyLinearState.participants - + + + +com.r3corda.core.testing / DummyLinearState / participants
    +
    +

    participants

    + +val participants: List<PublicKey>
    +Overrides ContractState.participants
    +

    A participant is any party that is able to consume this state in a valid transaction.

    +

    The list of participants is required for certain types of transactions. For example, when changing the notary +for this state (TransactionType.NotaryChange), every participants has to be involved and approve the transaction +so that they receive the updated state, and dont end up in a situation where they can no longer use a state +they possess, since someone consumed that state during the notary change process.

    +

    The participants list should normally be derived from the contents of the state. E.g. for Cash the participants +list should just contain the owner.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/thread.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/thread.html new file mode 100644 index 0000000000..fe71473f89 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-state/thread.html @@ -0,0 +1,17 @@ + + +DummyLinearState.thread - + + + +com.r3corda.core.testing / DummyLinearState / thread
    +
    +

    thread

    + +val thread: SecureHash
    +Overrides LinearState.thread
    +

    Unique thread id within the wallets of all parties

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/-init-.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/-init-.html new file mode 100644 index 0000000000..36c42a1c67 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/-init-.html @@ -0,0 +1,14 @@ + + +InMemoryWalletService.ClashingThreads.<init> - + + + +com.r3corda.core.testing / InMemoryWalletService / ClashingThreads / <init>
    +
    +

    <init>

    +ClashingThreads(threads: Set<SecureHash>, transactions: Iterable<WireTransaction>)
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/index.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/index.html new file mode 100644 index 0000000000..e1bd3df3f4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-clashing-threads/index.html @@ -0,0 +1,25 @@ + + +InMemoryWalletService.ClashingThreads - + + + +com.r3corda.core.testing / InMemoryWalletService / ClashingThreads
    +
    +

    ClashingThreads

    +class ClashingThreads : Exception
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +ClashingThreads(threads: Set<SecureHash>, transactions: Iterable<WireTransaction>)
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-init-.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-init-.html new file mode 100644 index 0000000000..def33d7482 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/-init-.html @@ -0,0 +1,17 @@ + + +InMemoryWalletService.<init> - + + + +com.r3corda.core.testing / InMemoryWalletService / <init>
    +
    +

    <init>

    +InMemoryWalletService(services: ServiceHub)
    +

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/clashing-threads.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/clashing-threads.html new file mode 100644 index 0000000000..b154bbd28c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/clashing-threads.html @@ -0,0 +1,15 @@ + + +InMemoryWalletService.clashingThreads - + + + +com.r3corda.core.testing / InMemoryWalletService / clashingThreads
    +
    +

    clashingThreads

    + +val Wallet.clashingThreads: Set<SecureHash>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/current-wallet.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/current-wallet.html new file mode 100644 index 0000000000..4c8165450e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/current-wallet.html @@ -0,0 +1,22 @@ + + +InMemoryWalletService.currentWallet - + + + +com.r3corda.core.testing / InMemoryWalletService / currentWallet
    +
    +

    currentWallet

    + +open val currentWallet: Wallet
    +Overrides WalletService.currentWallet
    +

    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.

    +

    Getter
    +

    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.

    +

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/index.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/index.html new file mode 100644 index 0000000000..719b6f1ea4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/index.html @@ -0,0 +1,156 @@ + + +InMemoryWalletService - + + + +com.r3corda.core.testing / InMemoryWalletService
    +
    +

    InMemoryWalletService

    +open class InMemoryWalletService : SingletonSerializeAsToken, WalletService
    +

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    +
    +
    +

    Exceptions

    + + + + + + + +
    +ClashingThreads +class ClashingThreads : Exception
    +

    Constructors

    + + + + + + + +
    +<init> +InMemoryWalletService(services: ServiceHub)

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +currentWallet +open val currentWallet: 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.

    +
    +linearHeads +open val linearHeads: Map<SecureHash, StateAndRef<LinearState>>

    Returns a snapshot of the heads of LinearStates

    +
    +updates +open val updates: <ERROR CLASS><Update>

    Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate +the update.

    +
    +

    Functions

    + + + + + + + +
    +notifyAll +open fun notifyAll(txns: Iterable<WireTransaction>): Wallet

    Possibly update the wallet by marking as spent states that these transactions consume, and adding any relevant +new states that they create. You should only insert transactions that have been successfully verified here

    +
    +

    Inherited Functions

    + + + + + + + + + + + + + + + + + + + + + + + +
    +linearHeadsOfType_ +open fun <T : LinearState> linearHeadsOfType_(stateType: Class<T>): Map<SecureHash, StateAndRef<T>>

    Returns the linearHeads only when the type of the state would be considered an instanceof the given type.

    +
    +notify +open fun notify(tx: WireTransaction): Wallet

    Same as notifyAll but with a single transaction.

    +
    +statesForRefs +open fun statesForRefs(refs: List<StateRef>): Map<StateRef, TransactionState<*>?>
    +toToken +open fun toToken(context: SerializeAsTokenContext): SerializationToken
    +whenConsumed +open fun whenConsumed(ref: StateRef): <ERROR CLASS><Update>

    Provide a Future for when a StateRef is consumed, which can be very useful in building tests.

    +
    +

    Companion Object Properties

    + + + + + + + +
    +clashingThreads +val Wallet.clashingThreads: Set<SecureHash>
    +

    Extension Functions

    + + + + + + + +
    +linearHeadsOfType +fun <T : LinearState> WalletService.linearHeadsOfType(): <ERROR CLASS>
    +

    Inheritors

    + + + + + + + +
    +NodeWalletService +class NodeWalletService : InMemoryWalletService

    Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).

    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/linear-heads.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/linear-heads.html new file mode 100644 index 0000000000..133aebc2ed --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/linear-heads.html @@ -0,0 +1,20 @@ + + +InMemoryWalletService.linearHeads - + + + +com.r3corda.core.testing / InMemoryWalletService / linearHeads
    +
    +

    linearHeads

    + +open val linearHeads: Map<SecureHash, StateAndRef<LinearState>>
    +Overrides WalletService.linearHeads
    +

    Returns a snapshot of the heads of LinearStates

    +

    Getter
    +

    Returns a snapshot of the heads of LinearStates

    +

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/notify-all.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/notify-all.html new file mode 100644 index 0000000000..fcd90b2fd4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/notify-all.html @@ -0,0 +1,22 @@ + + +InMemoryWalletService.notifyAll - + + + +com.r3corda.core.testing / InMemoryWalletService / notifyAll
    +
    +

    notifyAll

    + +open fun notifyAll(txns: Iterable<WireTransaction>): Wallet
    +Overrides WalletService.notifyAll
    +

    Possibly update the wallet by marking as spent states that these transactions consume, and adding any relevant +new states that they create. You should only insert transactions that have been successfully verified here

    +

    Returns the new wallet that resulted from applying the transactions (note: it may quickly become out of date).

    +

    TODO: Consider if theres a good way to enforce the must-be-verified requirement in the type system.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/updates.html b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/updates.html new file mode 100644 index 0000000000..7d63274c5d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-in-memory-wallet-service/updates.html @@ -0,0 +1,22 @@ + + +InMemoryWalletService.updates - + + + +com.r3corda.core.testing / InMemoryWalletService / updates
    +
    +

    updates

    + +open val updates: <ERROR CLASS><Update>
    +Overrides WalletService.updates
    +

    Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate +the update.

    +

    Getter
    +

    Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate +the update.

    +

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e.html new file mode 100644 index 0000000000..c2d0155e5c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ALICE - + + + +com.r3corda.core.testing / JavaTestHelpers / ALICE
    +
    +

    ALICE

    + +val ALICE: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-k-e-y.html new file mode 100644 index 0000000000..a39926500f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ALICE_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / ALICE_KEY
    +
    +

    ALICE_KEY

    + +val ALICE_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-p-u-b-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-p-u-b-k-e-y.html new file mode 100644 index 0000000000..aa5850890e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-i-c-e_-p-u-b-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ALICE_PUBKEY - + + + +com.r3corda.core.testing / JavaTestHelpers / ALICE_PUBKEY
    +
    +

    ALICE_PUBKEY

    + +val ALICE_PUBKEY: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-l_-t-e-s-t_-k-e-y-s.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-l_-t-e-s-t_-k-e-y-s.html new file mode 100644 index 0000000000..a63bdd244c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-a-l-l_-t-e-s-t_-k-e-y-s.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ALL_TEST_KEYS - + + + +com.r3corda.core.testing / JavaTestHelpers / ALL_TEST_KEYS
    +
    +

    ALL_TEST_KEYS

    + +val ALL_TEST_KEYS: List<KeyPair>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b.html new file mode 100644 index 0000000000..e64f4aabfd --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.BOB - + + + +com.r3corda.core.testing / JavaTestHelpers / BOB
    +
    +

    BOB

    + +val BOB: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-k-e-y.html new file mode 100644 index 0000000000..6eafd4a817 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.BOB_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / BOB_KEY
    +
    +

    BOB_KEY

    + +val BOB_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-p-u-b-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-p-u-b-k-e-y.html new file mode 100644 index 0000000000..f89f65e395 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-b-o-b_-p-u-b-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.BOB_PUBKEY - + + + +com.r3corda.core.testing / JavaTestHelpers / BOB_PUBKEY
    +
    +

    BOB_PUBKEY

    + +val BOB_PUBKEY: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y.html new file mode 100644 index 0000000000..cd78b02f82 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.DUMMY_NOTARY - + + + +com.r3corda.core.testing / JavaTestHelpers / DUMMY_NOTARY
    +
    +

    DUMMY_NOTARY

    + +val DUMMY_NOTARY: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y_-k-e-y.html new file mode 100644 index 0000000000..b714f40380 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-n-o-t-a-r-y_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.DUMMY_NOTARY_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / DUMMY_NOTARY_KEY
    +
    +

    DUMMY_NOTARY_KEY

    + +val DUMMY_NOTARY_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_1.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_1.html new file mode 100644 index 0000000000..c4c112f4a4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_1.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.DUMMY_PUBKEY_1 - + + + +com.r3corda.core.testing / JavaTestHelpers / DUMMY_PUBKEY_1
    +
    +

    DUMMY_PUBKEY_1

    + +val DUMMY_PUBKEY_1: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_2.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_2.html new file mode 100644 index 0000000000..ff32aea46e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-d-u-m-m-y_-p-u-b-k-e-y_2.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.DUMMY_PUBKEY_2 - + + + +com.r3corda.core.testing / JavaTestHelpers / DUMMY_PUBKEY_2
    +
    +

    DUMMY_PUBKEY_2

    + +val DUMMY_PUBKEY_2: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p.html new file mode 100644 index 0000000000..7eed093912 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MEGA_CORP - + + + +com.r3corda.core.testing / JavaTestHelpers / MEGA_CORP
    +
    +

    MEGA_CORP

    + +val MEGA_CORP: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-k-e-y.html new file mode 100644 index 0000000000..e334d6a277 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MEGA_CORP_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / MEGA_CORP_KEY
    +
    +

    MEGA_CORP_KEY

    + +val MEGA_CORP_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-p-u-b-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-p-u-b-k-e-y.html new file mode 100644 index 0000000000..c072691f19 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-e-g-a_-c-o-r-p_-p-u-b-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MEGA_CORP_PUBKEY - + + + +com.r3corda.core.testing / JavaTestHelpers / MEGA_CORP_PUBKEY
    +
    +

    MEGA_CORP_PUBKEY

    + +val MEGA_CORP_PUBKEY: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p.html new file mode 100644 index 0000000000..1f562d4661 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MINI_CORP - + + + +com.r3corda.core.testing / JavaTestHelpers / MINI_CORP
    +
    +

    MINI_CORP

    + +val MINI_CORP: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-k-e-y.html new file mode 100644 index 0000000000..5abe528f65 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MINI_CORP_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / MINI_CORP_KEY
    +
    +

    MINI_CORP_KEY

    + +val MINI_CORP_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-p-u-b-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-p-u-b-k-e-y.html new file mode 100644 index 0000000000..fb9bc69405 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-i-n-i_-c-o-r-p_-p-u-b-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MINI_CORP_PUBKEY - + + + +com.r3corda.core.testing / JavaTestHelpers / MINI_CORP_PUBKEY
    +
    +

    MINI_CORP_PUBKEY

    + +val MINI_CORP_PUBKEY: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-o-c-k_-i-d-e-n-t-i-t-y_-s-e-r-v-i-c-e.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-o-c-k_-i-d-e-n-t-i-t-y_-s-e-r-v-i-c-e.html new file mode 100644 index 0000000000..11bc0aba4f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-m-o-c-k_-i-d-e-n-t-i-t-y_-s-e-r-v-i-c-e.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.MOCK_IDENTITY_SERVICE - + + + +com.r3corda.core.testing / JavaTestHelpers / MOCK_IDENTITY_SERVICE
    +
    +

    MOCK_IDENTITY_SERVICE

    + +val MOCK_IDENTITY_SERVICE: MockIdentityService
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-k-e-y.html new file mode 100644 index 0000000000..cf59822e1e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ORACLE_KEY - + + + +com.r3corda.core.testing / JavaTestHelpers / ORACLE_KEY
    +
    +

    ORACLE_KEY

    + +val ORACLE_KEY: KeyPair
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-p-u-b-k-e-y.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-p-u-b-k-e-y.html new file mode 100644 index 0000000000..4ccccd3a91 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-o-r-a-c-l-e_-p-u-b-k-e-y.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.ORACLE_PUBKEY - + + + +com.r3corda.core.testing / JavaTestHelpers / ORACLE_PUBKEY
    +
    +

    ORACLE_PUBKEY

    + +val ORACLE_PUBKEY: PublicKey
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-t-e-s-t_-t-x_-t-i-m-e.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-t-e-s-t_-t-x_-t-i-m-e.html new file mode 100644 index 0000000000..34ec515a93 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/-t-e-s-t_-t-x_-t-i-m-e.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.TEST_TX_TIME - + + + +com.r3corda.core.testing / JavaTestHelpers / TEST_TX_TIME
    +
    +

    TEST_TX_TIME

    + +val TEST_TX_TIME: Instant
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/generate-state-ref.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/generate-state-ref.html new file mode 100644 index 0000000000..f904645a70 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/generate-state-ref.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.generateStateRef - + + + +com.r3corda.core.testing / JavaTestHelpers / generateStateRef
    +
    +

    generateStateRef

    + +fun generateStateRef(): StateRef
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/index.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/index.html new file mode 100644 index 0000000000..c6a9402f8c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/index.html @@ -0,0 +1,179 @@ + + +JavaTestHelpers - + + + +com.r3corda.core.testing / JavaTestHelpers
    +
    +

    JavaTestHelpers

    +object JavaTestHelpers
    +

    JAVA INTEROP. Please keep the following points in mind when extending the Kotlin DSL

    +
    • Annotate functions with Kotlin defaults with @JvmOverloads. This produces the relevant overloads for Java.

      +
    • Void closures in arguments are inconvenient in Java, use overloading to define non-closure variants as well.

      +
    • Top-level funs should be defined in a JavaTestHelpers object and annotated with @JvmStatic first and should be +referred to from the global fun. This allows static importing of JavaTestHelpers in Java tests, which mimicks +top-level funs.

      +
    • Top-level vals are trickier. DO NOT USE@JvmField INSIDEJavaTestHelpers. Its surprisingly easy to +introduce a static init cycle because of the way Kotlin compiles top-level things, which can cause +non-deterministic behaviour, including your field not being initialized at all Instead opt for a proper Kotlin +val either with a custom @JvmStatic get() or a lazy delegate if the initialiser has side-effects See examples below.

      +
    • Infix functions work as regular ones from Java, but symbols with spaces in them dont Define a camelCase variant +as well.

      +
    • varargs are exposed as array types in Java. Define overloads for common cases.

      +
    • The Int.DOLLARS syntax doesnt work from Java. To remedy add a @JvmStatic DOLLARS(Int) function to +JavaTestHelpers

      +

    +
    +
    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +ALICE +val ALICE: Party
    +ALICE_KEY +val ALICE_KEY: KeyPair
    +ALICE_PUBKEY +val ALICE_PUBKEY: PublicKey
    +ALL_TEST_KEYS +val ALL_TEST_KEYS: List<KeyPair>
    +BOB +val BOB: Party
    +BOB_KEY +val BOB_KEY: KeyPair
    +BOB_PUBKEY +val BOB_PUBKEY: PublicKey
    +DUMMY_NOTARY +val DUMMY_NOTARY: Party
    +DUMMY_NOTARY_KEY +val DUMMY_NOTARY_KEY: KeyPair
    +DUMMY_PUBKEY_1 +val DUMMY_PUBKEY_1: PublicKey
    +DUMMY_PUBKEY_2 +val DUMMY_PUBKEY_2: PublicKey
    +MEGA_CORP +val MEGA_CORP: Party
    +MEGA_CORP_KEY +val MEGA_CORP_KEY: KeyPair
    +MEGA_CORP_PUBKEY +val MEGA_CORP_PUBKEY: PublicKey
    +MINI_CORP +val MINI_CORP: Party
    +MINI_CORP_KEY +val MINI_CORP_KEY: KeyPair
    +MINI_CORP_PUBKEY +val MINI_CORP_PUBKEY: PublicKey
    +MOCK_IDENTITY_SERVICE +val MOCK_IDENTITY_SERVICE: MockIdentityService
    +ORACLE_KEY +val ORACLE_KEY: KeyPair
    +ORACLE_PUBKEY +val ORACLE_PUBKEY: PublicKey
    +TEST_TX_TIME +val TEST_TX_TIME: Instant
    +

    Functions

    + + + + + + + + + + + +
    +generateStateRef +fun generateStateRef(): StateRef
    +transaction +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/transaction.html b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/transaction.html new file mode 100644 index 0000000000..8fadb002ff --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-java-test-helpers/transaction.html @@ -0,0 +1,15 @@ + + +JavaTestHelpers.transaction - + + + +com.r3corda.core.testing / JavaTestHelpers / transaction
    +
    +

    transaction

    + +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/-init-.html b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/-init-.html index 6e54a5879c..1ef40c4b02 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/-init-.html +++ b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.testing / LabeledOutput / <init>

    <init>

    -LabeledOutput(label: String?, state: ContractState)
    +LabeledOutput(label: String?, state: TransactionState<*>)


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/index.html b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/index.html index 3715cfe423..69d1ffcbfb 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/index.html @@ -17,7 +17,7 @@ <init> -LabeledOutput(label: String?, state: ContractState) +LabeledOutput(label: String?, state: TransactionState<*>) @@ -34,7 +34,7 @@ state -val state: ContractState +val state: TransactionState<*> diff --git a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/state.html b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/state.html index 6ecb3e794d..d78dddd71c 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-labeled-output/state.html +++ b/docs/build/html/api/com.r3corda.core.testing/-labeled-output/state.html @@ -8,7 +8,7 @@

    state

    -val state: ContractState
    +val state: TransactionState<*>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-last-line-should-test-for-accept-or-failure.html b/docs/build/html/api/com.r3corda.core.testing/-last-line-should-test-for-accept-or-failure.html new file mode 100644 index 0000000000..190733ee28 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-last-line-should-test-for-accept-or-failure.html @@ -0,0 +1,18 @@ + + +LastLineShouldTestForAcceptOrFailure - + + + +com.r3corda.core.testing / LastLineShouldTestForAcceptOrFailure
    +
    +

    LastLineShouldTestForAcceptOrFailure

    +sealed class LastLineShouldTestForAcceptOrFailure
    +

    If you jumped here from a compiler error make sure the last line of your test tests for a transaction accept or fail +This is a dummy type that can only be instantiated by functions in this module. This way we can ensure that all tests +will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of +the triggered diagnostic

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-test-utils/index.html b/docs/build/html/api/com.r3corda.core.testing/-test-utils/index.html index 1d6e7b34a7..24d7a5b21e 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-test-utils/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-test-utils/index.html @@ -17,19 +17,19 @@ keypair -val keypair: KeyPair +val keypair: <ERROR CLASS> keypair2 -val keypair2: KeyPair +val keypair2: <ERROR CLASS> keypair3 -val keypair3: KeyPair +val keypair3: <ERROR CLASS> diff --git a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair.html b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair.html index 83f4b7eed6..1b988a93a3 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair.html +++ b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair.html @@ -8,7 +8,7 @@

    keypair

    -val keypair: KeyPair
    +val keypair: <ERROR CLASS>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair2.html b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair2.html index 7a9cd15792..86883a0259 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair2.html +++ b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair2.html @@ -8,7 +8,7 @@

    keypair2

    -val keypair2: KeyPair
    +val keypair2: <ERROR CLASS>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair3.html b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair3.html index eb34a4c02e..ade61abeae 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair3.html +++ b/docs/build/html/api/com.r3corda.core.testing/-test-utils/keypair3.html @@ -8,7 +8,7 @@

    keypair3

    -val keypair3: KeyPair
    +val keypair3: <ERROR CLASS>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/accepts.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/accepts.html index aaba5b7166..bc32cf90d4 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/accepts.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/accepts.html @@ -8,7 +8,7 @@

    accepts

    -fun accepts(time: Instant = TEST_TX_TIME): Unit
    +fun accepts(time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/chain.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/chain.html index 24b81e828d..96d8cbae1c 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/chain.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/chain.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / TransactionForTest / chain

    chain

    - -fun chain(vararg outputLabels: String, body: TransactionForTest.() -> Unit): TransactionForTest
    + +fun chain(vararg outputLabels: String, body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): TransactionForTest


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails requirement.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails requirement.html index 7ab883167e..ab6c436172 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails requirement.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails requirement.html @@ -8,7 +8,7 @@

    fails requirement

    -infix fun fails requirement(msg: String): Unit
    +infix fun fails requirement(msg: String): LastLineShouldTestForAcceptOrFailure

    Used to confirm that the test, when (implicitly) run against the .verify() method, fails with the text of the message



    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails-requirement.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails-requirement.html new file mode 100644 index 0000000000..c2efa380a2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/fails-requirement.html @@ -0,0 +1,15 @@ + + +TransactionForTest.failsRequirement - + + + +com.r3corda.core.testing / TransactionForTest / failsRequirement
    +
    +

    failsRequirement

    + +fun failsRequirement(msg: String): LastLineShouldTestForAcceptOrFailure
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/index.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/index.html index 58907c5576..d02d4a13ee 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/index.html @@ -42,6 +42,18 @@ val outStates: ArrayList<LabeledOutput> + + +signers + +val signers: LinkedHashSet<PublicKey> + + + +type + +val type: General +

    Functions

    @@ -51,13 +63,13 @@ accepts -fun accepts(time: Instant = TEST_TX_TIME): Unit +fun accepts(time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure chain -fun chain(vararg outputLabels: String, body: TransactionForTest.() -> Unit): TransactionForTest +fun chain(vararg outputLabels: String, body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): TransactionForTest @@ -69,14 +81,14 @@ fails requirement -infix fun fails requirement(msg: String): Unit

    Used to confirm that the test, when (implicitly) run against the .verify() method, fails with the text of the message

    +infix fun fails requirement(msg: String): LastLineShouldTestForAcceptOrFailure

    Used to confirm that the test, when (implicitly) run against the .verify() method, fails with the text of the message

    -fails_requirement +failsRequirement -fun fails_requirement(msg: String): Unit +fun failsRequirement(msg: String): LastLineShouldTestForAcceptOrFailure @@ -88,13 +100,14 @@ input -fun input(s: () -> ContractState): <ERROR CLASS> +fun input(s: () -> ContractState): Unit
    +fun input(s: ContractState): Unit rejects -fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): Unit +fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure @@ -112,7 +125,7 @@ tweak -fun tweak(body: TransactionForTest.() -> Unit): TransactionForTest +fun tweak(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure @@ -121,9 +134,16 @@ +addCommand + +fun addCommand(cmd: Command): Unit + + + arg -fun arg(vararg key: PublicKey, c: () -> CommandData): Unit +fun arg(vararg keys: PublicKey, c: () -> CommandData): Unit
    +fun arg(key: PublicKey, c: CommandData): Unit @@ -141,7 +161,8 @@ output -open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS> +open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS>
    +open fun output(label: String? = null, s: ContractState): <ERROR CLASS> @@ -154,7 +175,7 @@ transaction -fun transaction(body: TransactionForTest.() -> Unit): Unit +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): Unit diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/input.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/input.html index 6a0bbf71aa..a65e8c8e4a 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/input.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/input.html @@ -8,7 +8,9 @@

    input

    -fun input(s: () -> ContractState): <ERROR CLASS>
    +fun input(s: () -> ContractState): Unit
    + +fun input(s: ContractState): Unit


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/rejects.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/rejects.html index d7869bc5dc..d935254cde 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/rejects.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/rejects.html @@ -8,7 +8,7 @@

    rejects

    -fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): Unit
    +fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/tweak.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/tweak.html index df2ba5305d..ffe3501f75 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/tweak.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-for-test/tweak.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / TransactionForTest / tweak

    tweak

    - -fun tweak(body: TransactionForTest.() -> Unit): TransactionForTest
    + +fun tweak(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/index.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/index.html index 77ea845266..34f1d0a3fb 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/index.html @@ -28,14 +28,15 @@ roots -fun roots(body: Roots<T>.() -> Unit): Unit +fun roots(body: Roots<T>.() -> Unit): Unit

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place

    + transaction -fun transaction(vararg outputStates: LabeledOutput): Unit
    -fun transaction(body: WireTransactionDSL<T>.() -> Unit): Unit +fun transaction(vararg outputStates: LabeledOutput): Roots<T>fun transaction(body: WireTransactionDSL<T>.() -> Unit): Unit

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place

    + diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/roots.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/roots.html index d6100d78ad..8e634c8a58 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/roots.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/roots.html @@ -11,6 +11,7 @@ fun roots(body: Roots<T>.() -> Unit): Unit
    Deprecated: Does not nest

    +

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place



    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/transaction.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/transaction.html index 6aa05d2270..2f3cf367a1 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/transaction.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-roots/transaction.html @@ -8,11 +8,14 @@

    transaction

    -fun transaction(vararg outputStates: LabeledOutput): Unit
    +fun transaction(vararg outputStates: LabeledOutput): Roots<T>
    +
    +
    fun transaction(body: WireTransactionDSL<T>.() -> Unit): Unit
    Deprecated: Use the vararg form of transaction inside roots

    +

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place



    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-wire-transaction-d-s-l/index.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-wire-transaction-d-s-l/index.html index 69beac9a64..31263df945 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-wire-transaction-d-s-l/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/-wire-transaction-d-s-l/index.html @@ -42,6 +42,18 @@ val outStates: ArrayList<LabeledOutput> + + +signers + +val signers: LinkedHashSet<PublicKey> + + + +type + +val type: General +

    Functions

    @@ -66,9 +78,16 @@ +addCommand + +fun addCommand(cmd: Command): Unit + + + arg -fun arg(vararg key: PublicKey, c: () -> CommandData): Unit +fun arg(vararg keys: PublicKey, c: () -> CommandData): Unit
    +fun arg(key: PublicKey, c: CommandData): Unit @@ -86,7 +105,8 @@ output -open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS> +open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS>
    +open fun output(label: String? = null, s: ContractState): <ERROR CLASS> @@ -99,7 +119,7 @@ transaction -fun transaction(body: TransactionForTest.() -> Unit): Unit +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): Unit diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/index.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/index.html index f31843d0b5..3f4504c81e 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/index.html @@ -56,7 +56,7 @@ output -val String.output: T +val String.output: TransactionState<T> @@ -85,7 +85,7 @@ labelForState -fun labelForState(state: T): String? +fun labelForState(output: TransactionState<*>): String? @@ -128,7 +128,8 @@ transactionGroup -fun transactionGroup(body: TransactionGroupDSL<T>.() -> Unit): Unit +fun transactionGroup(body: TransactionGroupDSL<T>.() -> Unit): Unit

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place

    + diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/label-for-state.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/label-for-state.html index a3a0b174e5..b888166bea 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/label-for-state.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/label-for-state.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / TransactionGroupDSL / labelForState

    labelForState

    - -fun labelForState(state: T): String?
    + +fun labelForState(output: TransactionState<*>): String?


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/output.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/output.html index cd2f2399b6..6b60514e36 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/output.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/output.html @@ -8,7 +8,7 @@

    output

    -val String.output: T
    +val String.output: TransactionState<T>


    diff --git a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/transaction-group.html b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/transaction-group.html index 6a4836a971..3b1b92814d 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/transaction-group.html +++ b/docs/build/html/api/com.r3corda.core.testing/-transaction-group-d-s-l/transaction-group.html @@ -11,6 +11,7 @@ fun transactionGroup(body: TransactionGroupDSL<T>.() -> Unit): Unit
    Deprecated: Does not nest

    +

    Note: Dont delete, this is intended to trigger compiler diagnostic when the DSL primitive is used in the wrong place



    diff --git a/docs/build/html/api/com.r3corda.core.testing/index.html b/docs/build/html/api/com.r3corda.core.testing/index.html index ff20a008e5..15757b2eff 100644 --- a/docs/build/html/api/com.r3corda.core.testing/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/index.html @@ -18,12 +18,50 @@ +AlwaysSucceedContract + +class AlwaysSucceedContract : Contract + + + +DummyLinearState + +class DummyLinearState : LinearState + + + +InMemoryWalletService + +open class InMemoryWalletService : SingletonSerializeAsToken, WalletService

    This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience +method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist +states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

    + + + + +JavaTestHelpers + +object JavaTestHelpers

    JAVA INTEROP. Please keep the following points in mind when extending the Kotlin DSL

    + + + + LabeledOutput class LabeledOutput +LastLineShouldTestForAcceptOrFailure + +sealed class LastLineShouldTestForAcceptOrFailure

    If you jumped here from a compiler error make sure the last line of your test tests for a transaction accept or fail +This is a dummy type that can only be instantiated by functions in this module. This way we can ensure that all tests +will have as the last line either an accept or a failure test. The name is deliberately long to help make sense of +the triggered diagnostic

    + + + + TestUtils object TestUtils @@ -67,7 +105,7 @@ ALL_TEST_KEYS -val ALL_TEST_KEYS: <ERROR CLASS> +val ALL_TEST_KEYS: List<KeyPair> @@ -103,13 +141,13 @@ DUMMY_PUBKEY_1 -val DUMMY_PUBKEY_1: DummyPublicKey +val DUMMY_PUBKEY_1: PublicKey DUMMY_PUBKEY_2 -val DUMMY_PUBKEY_2: DummyPublicKey +val DUMMY_PUBKEY_2: PublicKey @@ -192,7 +230,7 @@ label -infix fun ContractState.label(label: String): LabeledOutput +infix fun TransactionState<*>.label(label: String): LabeledOutput @@ -205,7 +243,7 @@ transaction -fun transaction(body: TransactionForTest.() -> Unit): <ERROR CLASS> +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure diff --git a/docs/build/html/api/com.r3corda.core.testing/label.html b/docs/build/html/api/com.r3corda.core.testing/label.html index e9a112a252..192ab36b79 100644 --- a/docs/build/html/api/com.r3corda.core.testing/label.html +++ b/docs/build/html/api/com.r3corda.core.testing/label.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / label

    label

    - -infix fun ContractState.label(label: String): LabeledOutput
    + +infix fun TransactionState<*>.label(label: String): LabeledOutput


    diff --git a/docs/build/html/api/com.r3corda.core.testing/transaction.html b/docs/build/html/api/com.r3corda.core.testing/transaction.html index 0832008d7f..664582b199 100644 --- a/docs/build/html/api/com.r3corda.core.testing/transaction.html +++ b/docs/build/html/api/com.r3corda.core.testing/transaction.html @@ -7,8 +7,8 @@ com.r3corda.core.testing / transaction

    transaction

    - -fun transaction(body: TransactionForTest.() -> Unit): <ERROR CLASS>
    + +fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure


    diff --git a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/index.html b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/index.html new file mode 100644 index 0000000000..817bfd50d4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/index.html @@ -0,0 +1,33 @@ + + +NonEmptySetSerializer - + + + +com.r3corda.core.utilities / NonEmptySetSerializer
    +
    +

    NonEmptySetSerializer

    +object NonEmptySetSerializer
    +

    Custom serializer which understands it has to read in an item before +trying to construct the set.

    +
    +
    +

    Functions

    + + + + + + + + + + + +
    +read +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<NonEmptySet<Any>>): NonEmptySet<Any>
    +write +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: NonEmptySet<Any>): Unit
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/read.html b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/read.html new file mode 100644 index 0000000000..7fdaca5f02 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/read.html @@ -0,0 +1,15 @@ + + +NonEmptySetSerializer.read - + + + +com.r3corda.core.utilities / NonEmptySetSerializer / read
    +
    +

    read

    + +fun read(kryo: <ERROR CLASS>, input: <ERROR CLASS>, type: Class<NonEmptySet<Any>>): NonEmptySet<Any>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/write.html b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/write.html new file mode 100644 index 0000000000..ffee64de51 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set-serializer/write.html @@ -0,0 +1,15 @@ + + +NonEmptySetSerializer.write - + + + +com.r3corda.core.utilities / NonEmptySetSerializer / write
    +
    +

    write

    + +fun write(kryo: <ERROR CLASS>, output: <ERROR CLASS>, obj: NonEmptySet<Any>): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/-init-.html b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/-init-.html index 1639987355..3bd4e78196 100644 --- a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/-init-.html +++ b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/-init-.html @@ -7,9 +7,10 @@ com.r3corda.core.utilities / NonEmptySet / <init>

    <init>

    -NonEmptySet(initial: T, set: MutableSet<T> = mutableSetOf())
    +NonEmptySet(initial: T)

    A set which is constrained to ensure it can never be empty. An initial value must be provided at -construction, and attempting to remove the last element will cause an IllegalStateException.

    +construction, and attempting to remove the last element will cause an IllegalStateException. +The underlying set is exposed for Kryo to access, but should not be accessed directly.



    diff --git a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/index.html b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/index.html index 96e0d1a8a6..deda8d9a77 100644 --- a/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/index.html +++ b/docs/build/html/api/com.r3corda.core.utilities/-non-empty-set/index.html @@ -9,7 +9,8 @@

    NonEmptySet

    class NonEmptySet<T> : MutableSet<T>

    A set which is constrained to ensure it can never be empty. An initial value must be provided at -construction, and attempting to remove the last element will cause an IllegalStateException.

    +construction, and attempting to remove the last element will cause an IllegalStateException. +The underlying set is exposed for Kryo to access, but should not be accessed directly.



    Types

    @@ -30,8 +31,9 @@ construction, and attempting to remove the last element will cause an IllegalSta <init> -NonEmptySet(initial: T, set: MutableSet<T> = mutableSetOf())

    A set which is constrained to ensure it can never be empty. An initial value must be provided at -construction, and attempting to remove the last element will cause an IllegalStateException.

    +NonEmptySet(initial: T)

    A set which is constrained to ensure it can never be empty. An initial value must be provided at +construction, and attempting to remove the last element will cause an IllegalStateException. +The underlying set is exposed for Kryo to access, but should not be accessed directly.

    @@ -130,5 +132,19 @@ construction, and attempting to remove the last element will cause an IllegalSta +

    Extension Functions

    + + + + + + + +
    +noneOrSingle +fun <T> Iterable<T>.noneOrSingle(predicate: (T) -> Boolean): T?

    Returns the single element matching the given predicate, or null if element was not found, +or throws if more than one element was found.

    +fun <T> Iterable<T>.noneOrSingle(): T?

    Returns single element, or null if element was not found, or throws if more than one element was found.

    +
    diff --git a/docs/build/html/api/com.r3corda.core.utilities/-progress-tracker/-step/index.html b/docs/build/html/api/com.r3corda.core.utilities/-progress-tracker/-step/index.html index 1fae5cc2a1..3ab5534161 100644 --- a/docs/build/html/api/com.r3corda.core.utilities/-progress-tracker/-step/index.html +++ b/docs/build/html/api/com.r3corda.core.utilities/-progress-tracker/-step/index.html @@ -56,15 +56,15 @@ -ANNOUNCING +ANNOUNCING object ANNOUNCING : Step -ANNOUNCING +APPROVING -object ANNOUNCING : Step +object APPROVING : Step @@ -104,33 +104,9 @@ -FETCHING +LOADING -object FETCHING : Step - - - -FIXING - -object FIXING : Step - - - -ITERATING_DEALS - -object ITERATING_DEALS : Step - - - -ITERATING_FIXINGS - -object ITERATING_FIXINGS : Step - - - -LOCAL - -object LOCAL : Step +class LOADING : Step @@ -146,6 +122,12 @@ +NOTARY + +object NOTARY : Step + + + NOTIFYING object NOTIFYING : Step @@ -194,6 +176,12 @@ +REJECTING + +object REJECTING : Step + + + REQUESTING object REQUESTING : Step @@ -207,12 +195,6 @@ -SELF_ISSUING - -object SELF_ISSUING : Step - - - SENDING_SIGS object SENDING_SIGS : Step @@ -255,9 +237,9 @@ -STARTING_BUY +SIGNING -object STARTING_BUY : Step +object SIGNING : Step @@ -273,12 +255,6 @@ -TRADING - -object TRADING : Step - - - UNSTARTED object UNSTARTED : Step @@ -315,9 +291,9 @@ -WAITING_FOR_SELLER_TO_CONNECT +VERIFYING -object WAITING_FOR_SELLER_TO_CONNECT : Step +object VERIFYING : Step diff --git a/docs/build/html/api/com.r3corda.core.utilities/-time-window/-init-.html b/docs/build/html/api/com.r3corda.core.utilities/-time-window/-init-.html new file mode 100644 index 0000000000..05f9b25b92 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-time-window/-init-.html @@ -0,0 +1,15 @@ + + +TimeWindow.<init> - + + + +com.r3corda.core.utilities / TimeWindow / <init>
    +
    +

    <init>

    +TimeWindow(start: Instant, duration: Duration)
    +

    A class representing a window in time from a particular instant, lasting a specified duration.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-time-window/duration.html b/docs/build/html/api/com.r3corda.core.utilities/-time-window/duration.html new file mode 100644 index 0000000000..9b007335e3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-time-window/duration.html @@ -0,0 +1,15 @@ + + +TimeWindow.duration - + + + +com.r3corda.core.utilities / TimeWindow / duration
    +
    +

    duration

    + +val duration: Duration
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-time-window/end.html b/docs/build/html/api/com.r3corda.core.utilities/-time-window/end.html new file mode 100644 index 0000000000..f38321389b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-time-window/end.html @@ -0,0 +1,15 @@ + + +TimeWindow.end - + + + +com.r3corda.core.utilities / TimeWindow / end
    +
    +

    end

    + +val end: Instant
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-time-window/index.html b/docs/build/html/api/com.r3corda.core.utilities/-time-window/index.html new file mode 100644 index 0000000000..d8f11c21fa --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-time-window/index.html @@ -0,0 +1,50 @@ + + +TimeWindow - + + + +com.r3corda.core.utilities / TimeWindow
    +
    +

    TimeWindow

    +data class TimeWindow
    +

    A class representing a window in time from a particular instant, lasting a specified duration.

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +TimeWindow(start: Instant, duration: Duration)

    A class representing a window in time from a particular instant, lasting a specified duration.

    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +duration +val duration: Duration
    +end +val end: Instant
    +start +val start: Instant
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/-time-window/start.html b/docs/build/html/api/com.r3corda.core.utilities/-time-window/start.html new file mode 100644 index 0000000000..a30d34895b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/-time-window/start.html @@ -0,0 +1,15 @@ + + +TimeWindow.start - + + + +com.r3corda.core.utilities / TimeWindow / start
    +
    +

    start

    + +val start: Instant
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core.utilities/index.html b/docs/build/html/api/com.r3corda.core.utilities/index.html index ed1e868ade..8ad6fcfaf7 100644 --- a/docs/build/html/api/com.r3corda.core.utilities/index.html +++ b/docs/build/html/api/com.r3corda.core.utilities/index.html @@ -29,7 +29,16 @@ NonEmptySet class NonEmptySet<T> : MutableSet<T>

    A set which is constrained to ensure it can never be empty. An initial value must be provided at -construction, and attempting to remove the last element will cause an IllegalStateException.

    +construction, and attempting to remove the last element will cause an IllegalStateException. +The underlying set is exposed for Kryo to access, but should not be accessed directly.

    + + + + +NonEmptySetSerializer + +object NonEmptySetSerializer

    Custom serializer which understands it has to read in an item before +trying to construct the set.

    @@ -51,6 +60,13 @@ white box unit tests to ensure that code is accessing a data store as much as yo +TimeWindow + +data class TimeWindow

    A class representing a window in time from a particular instant, lasting a specified duration.

    + + + + UntrustworthyData class UntrustworthyData<T>

    A small utility to approximate taint tracking: if a method gives you back one of these, it means the data came from @@ -77,6 +93,15 @@ first. The wrapper helps you to avoid forgetting this vital step. Things you mig +suggestInterestRateAnnouncementTimeWindow + +fun suggestInterestRateAnnouncementTimeWindow(index: String, source: String, date: LocalDate): TimeWindow

    This whole file exists as short cuts to get demos working. In reality wed have static data and/or rules engine +defining things like this. It currently resides in the core module because it needs to be visible to the IRS +contract.

    + + + + trace fun <ERROR CLASS>.trace(msg: () -> String): Unit diff --git a/docs/build/html/api/com.r3corda.core.utilities/suggest-interest-rate-announcement-time-window.html b/docs/build/html/api/com.r3corda.core.utilities/suggest-interest-rate-announcement-time-window.html new file mode 100644 index 0000000000..9937a1844e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.utilities/suggest-interest-rate-announcement-time-window.html @@ -0,0 +1,18 @@ + + +suggestInterestRateAnnouncementTimeWindow - + + + +com.r3corda.core.utilities / suggestInterestRateAnnouncementTimeWindow
    +
    +

    suggestInterestRateAnnouncementTimeWindow

    + +fun suggestInterestRateAnnouncementTimeWindow(index: String, source: String, date: LocalDate): TimeWindow
    +

    This whole file exists as short cuts to get demos working. In reality wed have static data and/or rules engine +defining things like this. It currently resides in the core module because it needs to be visible to the IRS +contract.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core/-retryable-exception/index.html b/docs/build/html/api/com.r3corda.core/-retryable-exception/index.html index 8d3a1e7929..4040b705cc 100644 --- a/docs/build/html/api/com.r3corda.core/-retryable-exception/index.html +++ b/docs/build/html/api/com.r3corda.core/-retryable-exception/index.html @@ -28,5 +28,16 @@ again.

    +

    Inheritors

    + + + + + + + +
    +UnknownFix +class UnknownFix : RetryableException
    diff --git a/docs/build/html/api/com.r3corda.core/-thread-box/-init-.html b/docs/build/html/api/com.r3corda.core/-thread-box/-init-.html index 0774d4d124..c394dda3fc 100644 --- a/docs/build/html/api/com.r3corda.core/-thread-box/-init-.html +++ b/docs/build/html/api/com.r3corda.core/-thread-box/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core / ThreadBox / <init>

    <init>

    -ThreadBox(content: T, lock: Lock = ReentrantLock())
    +ThreadBox(content: T, lock: ReentrantLock = ReentrantLock())

    A threadbox is a simple utility that makes it harder to forget to take a lock before accessing some shared state. Simply define a private class to hold the data that must be grouped under the same lock, and then pass the only instance to the ThreadBox constructor. You can now use the locked method with a lambda to take the lock in a diff --git a/docs/build/html/api/com.r3corda.core/-thread-box/already-locked.html b/docs/build/html/api/com.r3corda.core/-thread-box/already-locked.html new file mode 100644 index 0000000000..eda07b192a --- /dev/null +++ b/docs/build/html/api/com.r3corda.core/-thread-box/already-locked.html @@ -0,0 +1,15 @@ + + +ThreadBox.alreadyLocked - + + + +com.r3corda.core / ThreadBox / alreadyLocked
    +
    +

    alreadyLocked

    + +inline fun <R> alreadyLocked(body: T.() -> R): R
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.core/-thread-box/index.html b/docs/build/html/api/com.r3corda.core/-thread-box/index.html index 27c0ac587a..285e300da9 100644 --- a/docs/build/html/api/com.r3corda.core/-thread-box/index.html +++ b/docs/build/html/api/com.r3corda.core/-thread-box/index.html @@ -30,7 +30,7 @@ private val state = ThreadBox(MutableState())

    <init> -ThreadBox(content: T, lock: Lock = ReentrantLock())

    A threadbox is a simple utility that makes it harder to forget to take a lock before accessing some shared state. +ThreadBox(content: T, lock: ReentrantLock = ReentrantLock())

    A threadbox is a simple utility that makes it harder to forget to take a lock before accessing some shared state. Simply define a private class to hold the data that must be grouped under the same lock, and then pass the only instance to the ThreadBox constructor. You can now use the locked method with a lambda to take the lock in a way that ensures itll be released if theres an exception.

    @@ -51,7 +51,7 @@ way that ensures itll be released if theres an exception.

    lock -val lock: Lock +val lock: ReentrantLock @@ -60,6 +60,12 @@ way that ensures itll be released if theres an exception.

    +alreadyLocked + +fun <R> alreadyLocked(body: T.() -> R): R + + + locked fun <R> locked(body: T.() -> R): R diff --git a/docs/build/html/api/com.r3corda.core/-thread-box/lock.html b/docs/build/html/api/com.r3corda.core/-thread-box/lock.html index ea2f2d3183..4bf17dbd2a 100644 --- a/docs/build/html/api/com.r3corda.core/-thread-box/lock.html +++ b/docs/build/html/api/com.r3corda.core/-thread-box/lock.html @@ -8,7 +8,7 @@

    lock

    -val lock: Lock
    +val lock: ReentrantLock


    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/-init-.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/-init-.html index b32761396e..bc918c5633 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/-init-.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/-init-.html @@ -7,7 +7,7 @@ com.r3corda.demos.protocols / AutoOfferProtocol / AutoOfferMessage / <init>

    <init>

    -AutoOfferMessage(otherSide: SingleMessageRecipient, otherSessionID: Long, dealBeingOffered: DealState)
    +AutoOfferMessage(otherSide: Party, notary: Party, otherSessionID: Long, dealBeingOffered: DealState)


    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/index.html index 58e910e398..155b64f0b8 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/index.html @@ -17,7 +17,7 @@ <init> -AutoOfferMessage(otherSide: SingleMessageRecipient, otherSessionID: Long, dealBeingOffered: DealState) +AutoOfferMessage(otherSide: Party, notary: Party, otherSessionID: Long, dealBeingOffered: DealState) @@ -32,6 +32,12 @@ +notary + +val notary: Party + + + otherSessionID val otherSessionID: Long @@ -40,7 +46,7 @@ otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/notary.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/notary.html new file mode 100644 index 0000000000..5bdd0c04c9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/notary.html @@ -0,0 +1,15 @@ + + +AutoOfferProtocol.AutoOfferMessage.notary - + + + +com.r3corda.demos.protocols / AutoOfferProtocol / AutoOfferMessage / notary
    +
    +

    notary

    + +val notary: Party
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/other-side.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/other-side.html index 1cf7c3c027..558b9a3b0a 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/other-side.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-auto-offer-message/other-side.html @@ -8,7 +8,7 @@

    otherSide

    -val otherSide: SingleMessageRecipient
    +val otherSide: Party


    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-requester/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-requester/index.html index b117c9a5df..928eb01c72 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-requester/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/-requester/index.html @@ -7,7 +7,7 @@ com.r3corda.demos.protocols / AutoOfferProtocol / Requester

    Requester

    -class Requester<T> : ProtocolLogic<SignedTransaction>
    +class Requester : ProtocolLogic<SignedTransaction>


    Types

    @@ -86,7 +86,9 @@ progress.

    serviceHub -val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

    +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    @@ -123,13 +125,13 @@ progress.

    send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/index.html index 3a2b47999b..3c35b6f502 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-auto-offer-protocol/index.html @@ -35,7 +35,7 @@ or the protocol would have to reach out to external systems (or users) to verify Requester -class Requester<T> : ProtocolLogic<SignedTransaction> +class Requester : ProtocolLogic<SignedTransaction> diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-exit-server-protocol/-broadcast/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-exit-server-protocol/-broadcast/index.html index 1d0b820801..124e892f4d 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-exit-server-protocol/-broadcast/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-exit-server-protocol/-broadcast/index.html @@ -67,7 +67,9 @@ progress.

    serviceHub -val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

    +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    @@ -98,13 +100,13 @@ progress.

    send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/call.html b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/call.html index e74d782932..5cdcdcc64d 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/call.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/call.html @@ -8,7 +8,7 @@

    call

    -fun call(): Boolean
    +fun call(): Unit
    Overrides ProtocolLogic.call

    This is where you fill out your business logic.


    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/index.html index 69e51151ba..daecc63e70 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-broadcast/index.html @@ -7,7 +7,7 @@ com.r3corda.demos.protocols / UpdateBusinessDayProtocol / Broadcast

    Broadcast

    -class Broadcast : ProtocolLogic<Boolean>
    +class Broadcast : ProtocolLogic<Unit>


    Types

    @@ -15,12 +15,6 @@ -LOCAL - -object LOCAL : Step - - - NOTIFYING object NOTIFYING : Step @@ -80,7 +74,9 @@ progress.

    serviceHub -val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

    +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    @@ -92,7 +88,7 @@ progress.

    call -fun call(): Boolean

    This is where you fill out your business logic.

    +fun call(): Unit

    This is where you fill out your business logic.

    @@ -111,13 +107,13 @@ progress.

    send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/-init-.html b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/-init-.html index 3574d1fd14..98068af277 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/-init-.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/-init-.html @@ -7,7 +7,7 @@ com.r3corda.demos.protocols / UpdateBusinessDayProtocol / UpdateBusinessDayMessage / <init>

    <init>

    -UpdateBusinessDayMessage(date: LocalDate, sessionID: Long)
    +UpdateBusinessDayMessage(date: LocalDate)


    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/index.html index e91da6a7cf..f02aafc24d 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/-update-business-day-message/index.html @@ -17,7 +17,7 @@ <init> -UpdateBusinessDayMessage(date: LocalDate, sessionID: Long) +UpdateBusinessDayMessage(date: LocalDate) @@ -30,12 +30,6 @@ val date: LocalDate - - -sessionID - -val sessionID: Long - diff --git a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/index.html b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/index.html index 55c3e68fe8..a040a9c03e 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/-update-business-day-protocol/index.html @@ -8,8 +8,7 @@

    UpdateBusinessDayProtocol

    object UpdateBusinessDayProtocol
    -

    This is a very temporary, demo-oriented way of initiating processing of temporal events and is not -intended as the way things will necessarily be done longer term

    +

    This is a less temporary, demo-oriented way of initiating processing of temporal events



    Types

    @@ -19,7 +18,7 @@ intended as the way things will necessarily be done longer term

    Broadcast -class Broadcast : ProtocolLogic<Boolean> +class Broadcast : ProtocolLogic<Unit> @@ -33,12 +32,6 @@ intended as the way things will necessarily be done longer term

    data class UpdateBusinessDayMessage - - -Updater - -class Updater : ProtocolLogic<Boolean> -

    Properties

    diff --git a/docs/build/html/api/com.r3corda.demos.protocols/index.html b/docs/build/html/api/com.r3corda.demos.protocols/index.html index 5bf4d880a2..1efe6028b2 100644 --- a/docs/build/html/api/com.r3corda.demos.protocols/index.html +++ b/docs/build/html/api/com.r3corda.demos.protocols/index.html @@ -28,8 +28,7 @@ API call from a single party without bi-directional access to the database of of UpdateBusinessDayProtocol -object UpdateBusinessDayProtocol

    This is a very temporary, demo-oriented way of initiating processing of temporal events and is not -intended as the way things will necessarily be done longer term

    +object UpdateBusinessDayProtocol

    This is a less temporary, demo-oriented way of initiating processing of temporal events

    diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/api-address-arg.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/api-address-arg.html new file mode 100644 index 0000000000..d94168971e --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/api-address-arg.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.apiAddressArg - + + + +com.r3corda.demos / CliParamsSpec / apiAddressArg
    +
    +

    apiAddressArg

    + +val apiAddressArg: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/base-directory-arg.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/base-directory-arg.html new file mode 100644 index 0000000000..72615e9d97 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/base-directory-arg.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.baseDirectoryArg - + + + +com.r3corda.demos / CliParamsSpec / baseDirectoryArg
    +
    +

    baseDirectoryArg

    + +val baseDirectoryArg: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-addr.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-addr.html new file mode 100644 index 0000000000..a3e0eedd5f --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-addr.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.fakeTradeWithAddr - + + + +com.r3corda.demos / CliParamsSpec / fakeTradeWithAddr
    +
    +

    fakeTradeWithAddr

    + +val fakeTradeWithAddr: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-identity-file.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-identity-file.html new file mode 100644 index 0000000000..3db3f5703e --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/fake-trade-with-identity-file.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.fakeTradeWithIdentityFile - + + + +com.r3corda.demos / CliParamsSpec / fakeTradeWithIdentityFile
    +
    +

    fakeTradeWithIdentityFile

    + +val fakeTradeWithIdentityFile: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/index.html new file mode 100644 index 0000000000..2f0d533c2f --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/index.html @@ -0,0 +1,79 @@ + + +CliParamsSpec - + + + +com.r3corda.demos / CliParamsSpec
    +
    +

    CliParamsSpec

    +object CliParamsSpec
    +
    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +apiAddressArg +val apiAddressArg: <ERROR CLASS>
    +baseDirectoryArg +val baseDirectoryArg: <ERROR CLASS>
    +fakeTradeWithAddr +val fakeTradeWithAddr: <ERROR CLASS>
    +fakeTradeWithIdentityFile +val fakeTradeWithIdentityFile: <ERROR CLASS>
    +networkAddressArg +val networkAddressArg: <ERROR CLASS>
    +networkMapIdentityFile +val networkMapIdentityFile: <ERROR CLASS>
    +networkMapNetAddr +val networkMapNetAddr: <ERROR CLASS>
    +nonOptions +val nonOptions: <ERROR CLASS>
    +parser +val parser: <ERROR CLASS>
    +roleArg +val roleArg: <ERROR CLASS>
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-address-arg.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-address-arg.html new file mode 100644 index 0000000000..b9aea4ed85 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-address-arg.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.networkAddressArg - + + + +com.r3corda.demos / CliParamsSpec / networkAddressArg
    +
    +

    networkAddressArg

    + +val networkAddressArg: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-identity-file.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-identity-file.html new file mode 100644 index 0000000000..1d0b30e893 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-identity-file.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.networkMapIdentityFile - + + + +com.r3corda.demos / CliParamsSpec / networkMapIdentityFile
    +
    +

    networkMapIdentityFile

    + +val networkMapIdentityFile: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-net-addr.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-net-addr.html new file mode 100644 index 0000000000..ce42e5428b --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/network-map-net-addr.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.networkMapNetAddr - + + + +com.r3corda.demos / CliParamsSpec / networkMapNetAddr
    +
    +

    networkMapNetAddr

    + +val networkMapNetAddr: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/non-options.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/non-options.html new file mode 100644 index 0000000000..2c38ab17e2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/non-options.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.nonOptions - + + + +com.r3corda.demos / CliParamsSpec / nonOptions
    +
    +

    nonOptions

    + +val nonOptions: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/parser.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/parser.html new file mode 100644 index 0000000000..c73d11aff3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/parser.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.parser - + + + +com.r3corda.demos / CliParamsSpec / parser
    +
    +

    parser

    + +val parser: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params-spec/role-arg.html b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/role-arg.html new file mode 100644 index 0000000000..488228857c --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params-spec/role-arg.html @@ -0,0 +1,15 @@ + + +CliParamsSpec.roleArg - + + + +com.r3corda.demos / CliParamsSpec / roleArg
    +
    +

    roleArg

    + +val roleArg: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/-init-.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/-init-.html new file mode 100644 index 0000000000..19d800d152 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/-init-.html @@ -0,0 +1,15 @@ + + +CliParams.DateChange.<init> - + + + +com.r3corda.demos / CliParams / DateChange / <init>
    +
    +

    <init>

    +DateChange(apiAddress: <ERROR CLASS>, dateString: String)
    +

    Corresponds to role Date

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/api-address.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/api-address.html new file mode 100644 index 0000000000..d8c5c51dd4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/api-address.html @@ -0,0 +1,15 @@ + + +CliParams.DateChange.apiAddress - + + + +com.r3corda.demos / CliParams / DateChange / apiAddress
    +
    +

    apiAddress

    + +val apiAddress: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/date-string.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/date-string.html new file mode 100644 index 0000000000..5c1834ddb8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/date-string.html @@ -0,0 +1,15 @@ + + +CliParams.DateChange.dateString - + + + +com.r3corda.demos / CliParams / DateChange / dateString
    +
    +

    dateString

    + +val dateString: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/index.html new file mode 100644 index 0000000000..38ff2d7315 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-date-change/index.html @@ -0,0 +1,44 @@ + + +CliParams.DateChange - + + + +com.r3corda.demos / CliParams / DateChange
    +
    +

    DateChange

    +class DateChange : CliParams
    +

    Corresponds to role Date

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +DateChange(apiAddress: <ERROR CLASS>, dateString: String)

    Corresponds to role Date

    +
    +

    Properties

    + + + + + + + + + + + +
    +apiAddress +val apiAddress: <ERROR CLASS>
    +dateString +val dateString: String
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/-init-.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/-init-.html new file mode 100644 index 0000000000..198ea5dfb3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/-init-.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.<init> - + + + +com.r3corda.demos / CliParams / RunNode / <init>
    +
    +

    <init>

    +RunNode(node: IRSDemoNode, dir: Path, networkAddress: <ERROR CLASS>, apiAddress: <ERROR CLASS>, mapAddress: String, identityFile: Path, tradeWithAddrs: List<String>, tradeWithIdentities: List<Path>, uploadRates: Boolean, defaultLegalName: String, autoSetup: Boolean)
    +

    Corresponds to roles NodeA and NodeB

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/api-address.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/api-address.html new file mode 100644 index 0000000000..207d1be562 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/api-address.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.apiAddress - + + + +com.r3corda.demos / CliParams / RunNode / apiAddress
    +
    +

    apiAddress

    + +val apiAddress: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/auto-setup.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/auto-setup.html new file mode 100644 index 0000000000..dab910fb3b --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/auto-setup.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.autoSetup - + + + +com.r3corda.demos / CliParams / RunNode / autoSetup
    +
    +

    autoSetup

    + +val autoSetup: Boolean
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/default-legal-name.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/default-legal-name.html new file mode 100644 index 0000000000..ef500bd37d --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/default-legal-name.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.defaultLegalName - + + + +com.r3corda.demos / CliParams / RunNode / defaultLegalName
    +
    +

    defaultLegalName

    + +val defaultLegalName: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/dir.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/dir.html new file mode 100644 index 0000000000..a0a5a6bdd5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/dir.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.dir - + + + +com.r3corda.demos / CliParams / RunNode / dir
    +
    +

    dir

    + +val dir: Path
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/identity-file.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/identity-file.html new file mode 100644 index 0000000000..68a403a966 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/identity-file.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.identityFile - + + + +com.r3corda.demos / CliParams / RunNode / identityFile
    +
    +

    identityFile

    + +val identityFile: Path
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/index.html new file mode 100644 index 0000000000..566e96ad02 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/index.html @@ -0,0 +1,98 @@ + + +CliParams.RunNode - + + + +com.r3corda.demos / CliParams / RunNode
    +
    +

    RunNode

    +class RunNode : CliParams
    +

    Corresponds to roles NodeA and NodeB

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +RunNode(node: IRSDemoNode, dir: Path, networkAddress: <ERROR CLASS>, apiAddress: <ERROR CLASS>, mapAddress: String, identityFile: Path, tradeWithAddrs: List<String>, tradeWithIdentities: List<Path>, uploadRates: Boolean, defaultLegalName: String, autoSetup: Boolean)

    Corresponds to roles NodeA and NodeB

    +
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +apiAddress +val apiAddress: <ERROR CLASS>
    +autoSetup +val autoSetup: Boolean
    +defaultLegalName +val defaultLegalName: String
    +dir +val dir: Path
    +identityFile +val identityFile: Path
    +mapAddress +val mapAddress: String
    +networkAddress +val networkAddress: <ERROR CLASS>
    +node +val node: IRSDemoNode
    +tradeWithAddrs +val tradeWithAddrs: List<String>
    +tradeWithIdentities +val tradeWithIdentities: List<Path>
    +uploadRates +val uploadRates: Boolean
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/map-address.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/map-address.html new file mode 100644 index 0000000000..355322d9d5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/map-address.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.mapAddress - + + + +com.r3corda.demos / CliParams / RunNode / mapAddress
    +
    +

    mapAddress

    + +val mapAddress: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/network-address.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/network-address.html new file mode 100644 index 0000000000..dae97d4f86 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/network-address.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.networkAddress - + + + +com.r3corda.demos / CliParams / RunNode / networkAddress
    +
    +

    networkAddress

    + +val networkAddress: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/node.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/node.html new file mode 100644 index 0000000000..c5e15b8642 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/node.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.node - + + + +com.r3corda.demos / CliParams / RunNode / node
    +
    +

    node

    + +val node: IRSDemoNode
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-addrs.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-addrs.html new file mode 100644 index 0000000000..452d1005d5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-addrs.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.tradeWithAddrs - + + + +com.r3corda.demos / CliParams / RunNode / tradeWithAddrs
    +
    +

    tradeWithAddrs

    + +val tradeWithAddrs: List<String>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-identities.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-identities.html new file mode 100644 index 0000000000..b9a531ffca --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/trade-with-identities.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.tradeWithIdentities - + + + +com.r3corda.demos / CliParams / RunNode / tradeWithIdentities
    +
    +

    tradeWithIdentities

    + +val tradeWithIdentities: List<Path>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/upload-rates.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/upload-rates.html new file mode 100644 index 0000000000..6f178642e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-run-node/upload-rates.html @@ -0,0 +1,15 @@ + + +CliParams.RunNode.uploadRates - + + + +com.r3corda.demos / CliParams / RunNode / uploadRates
    +
    +

    uploadRates

    + +val uploadRates: Boolean
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/-init-.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/-init-.html new file mode 100644 index 0000000000..f678ac85fb --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/-init-.html @@ -0,0 +1,15 @@ + + +CliParams.SetupNode.<init> - + + + +com.r3corda.demos / CliParams / SetupNode / <init>
    +
    +

    <init>

    +SetupNode(node: IRSDemoNode, dir: Path, defaultLegalName: String)
    +

    Corresponds to roles SetupNodeA and SetupNodeB

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/default-legal-name.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/default-legal-name.html new file mode 100644 index 0000000000..dbc059fe4f --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/default-legal-name.html @@ -0,0 +1,15 @@ + + +CliParams.SetupNode.defaultLegalName - + + + +com.r3corda.demos / CliParams / SetupNode / defaultLegalName
    +
    +

    defaultLegalName

    + +val defaultLegalName: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/dir.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/dir.html new file mode 100644 index 0000000000..0177c35d78 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/dir.html @@ -0,0 +1,15 @@ + + +CliParams.SetupNode.dir - + + + +com.r3corda.demos / CliParams / SetupNode / dir
    +
    +

    dir

    + +val dir: Path
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/index.html new file mode 100644 index 0000000000..c512dc861d --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/index.html @@ -0,0 +1,50 @@ + + +CliParams.SetupNode - + + + +com.r3corda.demos / CliParams / SetupNode
    +
    +

    SetupNode

    +class SetupNode : CliParams
    +

    Corresponds to roles SetupNodeA and SetupNodeB

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +SetupNode(node: IRSDemoNode, dir: Path, defaultLegalName: String)

    Corresponds to roles SetupNodeA and SetupNodeB

    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +defaultLegalName +val defaultLegalName: String
    +dir +val dir: Path
    +node +val node: IRSDemoNode
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/node.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/node.html new file mode 100644 index 0000000000..06ce7765ce --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-setup-node/node.html @@ -0,0 +1,15 @@ + + +CliParams.SetupNode.node - + + + +com.r3corda.demos / CliParams / SetupNode / node
    +
    +

    node

    + +val node: IRSDemoNode
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/-init-.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/-init-.html new file mode 100644 index 0000000000..796082aa17 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/-init-.html @@ -0,0 +1,15 @@ + + +CliParams.Trade.<init> - + + + +com.r3corda.demos / CliParams / Trade / <init>
    +
    +

    <init>

    +Trade(apiAddress: <ERROR CLASS>, tradeId: String)
    +

    Corresponds to role Trade

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/api-address.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/api-address.html new file mode 100644 index 0000000000..bebf995bd1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/api-address.html @@ -0,0 +1,15 @@ + + +CliParams.Trade.apiAddress - + + + +com.r3corda.demos / CliParams / Trade / apiAddress
    +
    +

    apiAddress

    + +val apiAddress: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/index.html new file mode 100644 index 0000000000..2f9cb06bf4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/index.html @@ -0,0 +1,44 @@ + + +CliParams.Trade - + + + +com.r3corda.demos / CliParams / Trade
    +
    +

    Trade

    +class Trade : CliParams
    +

    Corresponds to role Trade

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +Trade(apiAddress: <ERROR CLASS>, tradeId: String)

    Corresponds to role Trade

    +
    +

    Properties

    + + + + + + + + + + + +
    +apiAddress +val apiAddress: <ERROR CLASS>
    +tradeId +val tradeId: String
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/trade-id.html b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/trade-id.html new file mode 100644 index 0000000000..4c7da1e4b4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/-trade/trade-id.html @@ -0,0 +1,15 @@ + + +CliParams.Trade.tradeId - + + + +com.r3corda.demos / CliParams / Trade / tradeId
    +
    +

    tradeId

    + +val tradeId: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/default-base-directory.html b/docs/build/html/api/com.r3corda.demos/-cli-params/default-base-directory.html new file mode 100644 index 0000000000..020af40ee5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/default-base-directory.html @@ -0,0 +1,15 @@ + + +CliParams.defaultBaseDirectory - + + + +com.r3corda.demos / CliParams / defaultBaseDirectory
    +
    +

    defaultBaseDirectory

    + +val defaultBaseDirectory: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/index.html b/docs/build/html/api/com.r3corda.demos/-cli-params/index.html new file mode 100644 index 0000000000..09566ecbea --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/index.html @@ -0,0 +1,109 @@ + + +CliParams - + + + +com.r3corda.demos / CliParams
    +
    +

    CliParams

    +sealed class CliParams
    +

    Parsed command line parameters.

    +
    +
    +

    Types

    + + + + + + + + + + + + + + + + + + + +
    +DateChange +class DateChange : CliParams

    Corresponds to role Date

    +
    +RunNode +class RunNode : CliParams

    Corresponds to roles NodeA and NodeB

    +
    +SetupNode +class SetupNode : CliParams

    Corresponds to roles SetupNodeA and SetupNodeB

    +
    +Trade +class Trade : CliParams

    Corresponds to role Trade

    +
    +

    Companion Object Properties

    + + + + + + + +
    +defaultBaseDirectory +val defaultBaseDirectory: String
    +

    Companion Object Functions

    + + + + + + + + + + + +
    +legalName +fun legalName(node: IRSDemoNode): String
    +parse +fun parse(options: <ERROR CLASS>): CliParams
    +

    Inheritors

    + + + + + + + + + + + + + + + + + + + +
    +DateChange +class DateChange : CliParams

    Corresponds to role Date

    +
    +RunNode +class RunNode : CliParams

    Corresponds to roles NodeA and NodeB

    +
    +SetupNode +class SetupNode : CliParams

    Corresponds to roles SetupNodeA and SetupNodeB

    +
    +Trade +class Trade : CliParams

    Corresponds to role Trade

    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/legal-name.html b/docs/build/html/api/com.r3corda.demos/-cli-params/legal-name.html new file mode 100644 index 0000000000..96ac0f5273 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/legal-name.html @@ -0,0 +1,15 @@ + + +CliParams.legalName - + + + +com.r3corda.demos / CliParams / legalName
    +
    +

    legalName

    + +fun legalName(node: IRSDemoNode): String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-cli-params/parse.html b/docs/build/html/api/com.r3corda.demos/-cli-params/parse.html new file mode 100644 index 0000000000..dfc7ecdb75 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-cli-params/parse.html @@ -0,0 +1,15 @@ + + +CliParams.parse - + + + +com.r3corda.demos / CliParams / parse
    +
    +

    parse

    + +fun parse(options: <ERROR CLASS>): CliParams
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-d-e-f-a-u-l-t_-b-a-s-e_-d-i-r-e-c-t-o-r-y.html b/docs/build/html/api/com.r3corda.demos/-d-e-f-a-u-l-t_-b-a-s-e_-d-i-r-e-c-t-o-r-y.html new file mode 100644 index 0000000000..b4c2d4a5e0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-d-e-f-a-u-l-t_-b-a-s-e_-d-i-r-e-c-t-o-r-y.html @@ -0,0 +1,15 @@ + + +DEFAULT_BASE_DIRECTORY - + + + +com.r3corda.demos / DEFAULT_BASE_DIRECTORY
    +
    +

    DEFAULT_BASE_DIRECTORY

    + +val DEFAULT_BASE_DIRECTORY: String
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-a.html b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-a.html new file mode 100644 index 0000000000..76fb767ede --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-a.html @@ -0,0 +1,25 @@ + + +IRSDemoNode.NodeA - + + + +com.r3corda.demos / IRSDemoNode / NodeA
    +
    +

    NodeA

    +NodeA
    +
    +
    +

    Inherited Properties

    + + + + + + + +
    +other +val other: IRSDemoNode
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-b.html b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-b.html new file mode 100644 index 0000000000..f0e3845da4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/-node-b.html @@ -0,0 +1,25 @@ + + +IRSDemoNode.NodeB - + + + +com.r3corda.demos / IRSDemoNode / NodeB
    +
    +

    NodeB

    +NodeB
    +
    +
    +

    Inherited Properties

    + + + + + + + +
    +other +val other: IRSDemoNode
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/index.html b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/index.html new file mode 100644 index 0000000000..af7812a100 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/index.html @@ -0,0 +1,42 @@ + + +IRSDemoNode - + + + +com.r3corda.demos / IRSDemoNode
    +
    +

    IRSDemoNode

    +enum class IRSDemoNode
    +
    +
    +

    Enum Values

    + + + + + + + + + + + +
    +NodeA +
    +NodeB +
    +

    Properties

    + + + + + + + +
    +other +val other: IRSDemoNode
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/other.html b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/other.html new file mode 100644 index 0000000000..c918904272 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-node/other.html @@ -0,0 +1,15 @@ + + +IRSDemoNode.other - + + + +com.r3corda.demos / IRSDemoNode / other
    +
    +

    other

    + +val other: IRSDemoNode
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-role/index.html b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-role/index.html index a0f781db98..ae2ec21cf5 100644 --- a/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-role/index.html +++ b/docs/build/html/api/com.r3corda.demos/-i-r-s-demo-role/index.html @@ -8,6 +8,13 @@

    IRSDemoRole

    enum class IRSDemoRole
    +

    Roles. There are 4 modes this demo can be run:

    +
    • SetupNodeA/SetupNodeB: Creates and sets up the necessary directories for nodes

      +
    • NodeA/NodeB: Starts the nodes themselves

      +
    • Trade: Uploads an example trade

      +
    • DateChange: Changes the demos date

      +

    +


    Enum Values

    diff --git a/docs/build/html/api/com.r3corda.demos/index.html b/docs/build/html/api/com.r3corda.demos/index.html index 14e5f3bc28..f6911c3ed6 100644 --- a/docs/build/html/api/com.r3corda.demos/index.html +++ b/docs/build/html/api/com.r3corda.demos/index.html @@ -12,6 +12,19 @@ +CliParams + +sealed class CliParams

    Parsed command line parameters.

    + + + + +CliParamsSpec + +object CliParamsSpec + + + DemoClock class DemoClock : MutableClock, SerializeAsToken

    A Clock that can have the date advanced for use in demos

    @@ -19,9 +32,16 @@ +IRSDemoNode + +enum class IRSDemoNode + + + IRSDemoRole -enum class IRSDemoRole +enum class IRSDemoRole

    Roles. There are 4 modes this demo can be run:

    + @@ -29,18 +49,6 @@ enum class Role - - -TraderDemoProtocolBuyer - -class TraderDemoProtocolBuyer : ProtocolLogic<Unit> - - - -TraderDemoProtocolSeller - -class TraderDemoProtocolSeller : ProtocolLogic<Unit> -

    Properties

    @@ -48,15 +56,15 @@ -DEMO_TOPIC +DEFAULT_BASE_DIRECTORY -val DEMO_TOPIC: String +val DEFAULT_BASE_DIRECTORY: String -DIRNAME +DEMO_TOPIC -val DIRNAME: String +val DEMO_TOPIC: String @@ -74,27 +82,15 @@ service.

    -parseOptions +runIRSDemo -fun parseOptions(args: Array<String>, parser: <ERROR CLASS>): <ERROR CLASS> +fun runIRSDemo(args: Array<String>): Int -runBuyer +runTraderDemo -fun runBuyer(node: Node): Unit - - - -runSeller - -fun runSeller(myNetAddr: <ERROR CLASS>, node: Node, theirNetAddr: <ERROR CLASS>): Unit - - - -setupDirectory - -fun setupDirectory(mode: Role): Path +fun runTraderDemo(args: Array<String>): Int diff --git a/docs/build/html/api/com.r3corda.demos/run-i-r-s-demo.html b/docs/build/html/api/com.r3corda.demos/run-i-r-s-demo.html new file mode 100644 index 0000000000..c0009b260c --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/run-i-r-s-demo.html @@ -0,0 +1,15 @@ + + +runIRSDemo - + + + +com.r3corda.demos / runIRSDemo
    +
    +

    runIRSDemo

    + +fun runIRSDemo(args: Array<String>): Int
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.demos/run-trader-demo.html b/docs/build/html/api/com.r3corda.demos/run-trader-demo.html new file mode 100644 index 0000000000..25c694b6e5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.demos/run-trader-demo.html @@ -0,0 +1,15 @@ + + +runTraderDemo - + + + +com.r3corda.demos / runTraderDemo
    +
    +

    runTraderDemo

    + +fun runTraderDemo(args: Array<String>): Int
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-states.html b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-states.html index 666254854a..99fa888306 100644 --- a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-states.html +++ b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-states.html @@ -8,7 +8,7 @@

    fetchStates

    -abstract fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
    +abstract fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?>


    diff --git a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-transactions.html b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-transactions.html index cd68eed4fa..f4b7999730 100644 --- a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-transactions.html +++ b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/fetch-transactions.html @@ -13,8 +13,8 @@

    Parameters

    txs - The hashes (from StateRef.txhash returned from queryStates) you would like full transactions for.
    -Return
    -null values indicate missing transactions from the requested list.
    +

    Return
    +null values indicate missing transactions from the requested list.



    diff --git a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/index.html b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/index.html index 67fa5431c0..0ee69e7c6b 100644 --- a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/index.html +++ b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/index.html @@ -46,7 +46,7 @@ successful, otherwise exception is thrown.

    fetchStates -abstract fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?> +abstract fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?> @@ -92,6 +92,13 @@ to avoid calling fetchLedgerTransactions() many times.

    abstract fun serverTime(): LocalDateTime

    Report current UTC time as understood by the platform.

    + + +status + +abstract fun status(): <ERROR CLASS>

    Report whether this node is started up or not

    + +

    Inheritors

    diff --git a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/query-states.html b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/query-states.html index 9f97e27528..c0041e792f 100644 --- a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/query-states.html +++ b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/query-states.html @@ -15,8 +15,8 @@ to avoid calling fetchLedgerTransactions() many times.

    Parameters

    query - Some "where clause" like expression.
    -Return
    -Zero or more matching States.
    +

    Return
    +Zero or more matching States.



    diff --git a/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/status.html b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/status.html new file mode 100644 index 0000000000..67b36d865d --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.api/-a-p-i-server/status.html @@ -0,0 +1,16 @@ + + +APIServer.status - + + + +com.r3corda.node.api / APIServer / status
    +
    +

    status

    + +abstract fun status(): <ERROR CLASS>
    +

    Report whether this node is started up or not

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/-init-.html b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/-init-.html index bd07e8a5f1..f7b77c79d6 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/-init-.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.internal.testing / IRSSimulation / <init>

    <init>

    -IRSSimulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)
    +IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)

    A simulation in which banks execute interest rate swaps with each other, including the fixing events.



    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/index.html index 37ec2eb368..fc5808a6f4 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/index.html @@ -18,7 +18,7 @@ <init> -IRSSimulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)

    A simulation in which banks execute interest rate swaps with each other, including the fixing events.

    +IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)

    A simulation in which banks execute interest rate swaps with each other, including the fixing events.

    @@ -63,9 +63,15 @@ -currentDay +clocks -var currentDay: LocalDate

    The current simulated date. By default this never changes. If you want it to change, you should do so from +val clocks: <ERROR CLASS> + + + +currentDateAndTime + +var currentDateAndTime: LocalDateTime

    The current simulated date. By default this never changes. If you want it to change, you should do so from within your overridden iterate call. Changes in the current day surface in the dateChanges observable.

    @@ -73,7 +79,7 @@ within your overridden iterate call. C dateChanges -val dateChanges: <ERROR CLASS><LocalDate> +val dateChanges: <ERROR CLASS><LocalDateTime> @@ -115,6 +121,12 @@ in the UI somewhere.

    +networkSendManuallyPumped + +val networkSendManuallyPumped: Boolean + + + notary val notary: SimulatedNode @@ -170,15 +182,15 @@ network bringup has been simulated.

    -linkConsensus +showConsensusFor -fun linkConsensus(nodes: Collection<SimulatedNode>, protocol: ProtocolLogic<*>): Unit +fun showConsensusFor(nodes: List<SimulatedNode>): Unit -linkProtocolProgress +showProgressFor -fun linkProtocolProgress(node: SimulatedNode, protocol: ProtocolLogic<*>): Unit +fun showProgressFor(nodes: List<SimulatedNode>): Unit @@ -190,7 +202,7 @@ network bringup has been simulated.

    startTradingCircle -fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc +fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc each time the returned future completes.

    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/iterate.html b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/iterate.html index 4475f334a6..2d2be5183f 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/iterate.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-i-r-s-simulation/iterate.html @@ -17,8 +17,8 @@ interesting happening, or control the precise speed at which things operate (bey is a useful way to do things.



    -Return
    -the message that was processed, or null if no node accepted a message in this round.
    +

    Return
    +the message that was processed, or null if no node accepted a message in this round.



    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-init-.html b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-init-.html index 7e0cab9adb..b31eff5de1 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-init-.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.internal.testing / MockNetwork / <init>

    <init>

    -MockNetwork(threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)
    +MockNetwork(networkSendManuallyPumped: Boolean = false, threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)

    A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing. Components that do IO are either swapped out for mocks, or pointed to a Jimfs in memory filesystem.

    Mock network nodes require manual pumping by default: they will not run asynchronous. This means that diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-mock-node/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-mock-node/index.html index 5bd4b8f5f4..015fd14f10 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-mock-node/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/-mock-node/index.html @@ -176,6 +176,12 @@ +scheduler + +lateinit var scheduler: SchedulerService + + + services val services: ServiceHubInternal @@ -203,7 +209,7 @@ storage -lateinit var storage: StorageService +lateinit var storage: TxWritableStorageService @@ -272,9 +278,15 @@ +createNodeDir + +fun createNodeDir(): Unit + + + initialiseStorageService -open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage> +open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage> @@ -302,6 +314,13 @@ +setup + +open fun setup(): AbstractNode

    Run any tasks that are needed to ensure the node is in a correct state before running start()

    + + + + stop open fun stop(): Unit diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/index.html index 1f3f355485..b67c37ef47 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-mock-network/index.html @@ -50,7 +50,7 @@ method.

    <init> -MockNetwork(threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)

    A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing. +MockNetwork(networkSendManuallyPumped: Boolean = false, threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)

    A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing. Components that do IO are either swapped out for mocks, or pointed to a Jimfs in memory filesystem.

    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/-init-.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/-init-.html index 9fb34180e1..e450f6b867 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/-init-.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.internal.testing / Simulation / <init>

    <init>

    -Simulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)
    +Simulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)

    Base class for network simulations that are based on the unit test / mock environment.

    Sets up some nodes that can run protocols between each other, and exposes their progress trackers. Provides banks in a few cities around the world.

    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/clocks.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/clocks.html new file mode 100644 index 0000000000..ba7bc1a4fc --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/clocks.html @@ -0,0 +1,15 @@ + + +Simulation.clocks - + + + +com.r3corda.node.internal.testing / Simulation / clocks
    +
    +

    clocks

    + +val clocks: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/current-date-and-time.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/current-date-and-time.html new file mode 100644 index 0000000000..f8c7cae3b4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/current-date-and-time.html @@ -0,0 +1,17 @@ + + +Simulation.currentDateAndTime - + + + +com.r3corda.node.internal.testing / Simulation / currentDateAndTime
    +
    +

    currentDateAndTime

    + +var currentDateAndTime: LocalDateTime
    +

    The current simulated date. By default this never changes. If you want it to change, you should do so from +within your overridden iterate call. Changes in the current day surface in the dateChanges observable.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/date-changes.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/date-changes.html index 183466f7ac..58391e1b23 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/date-changes.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/date-changes.html @@ -8,7 +8,7 @@

    dateChanges

    -val dateChanges: <ERROR CLASS><LocalDate>
    +val dateChanges: <ERROR CLASS><LocalDateTime>


    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/index.html index 013fab1853..52675fe3fc 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/index.html @@ -63,7 +63,7 @@ in a few cities around the world.

    <init> -Simulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)

    Base class for network simulations that are based on the unit test / mock environment.

    +Simulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)

    Base class for network simulations that are based on the unit test / mock environment.

    @@ -97,9 +97,15 @@ in a few cities around the world.

    -currentDay +clocks -var currentDay: LocalDate

    The current simulated date. By default this never changes. If you want it to change, you should do so from +val clocks: <ERROR CLASS> + + + +currentDateAndTime + +var currentDateAndTime: LocalDateTime

    The current simulated date. By default this never changes. If you want it to change, you should do so from within your overridden iterate call. Changes in the current day surface in the dateChanges observable.

    @@ -107,7 +113,7 @@ within your overridden iterate call. Changes in the c dateChanges -val dateChanges: <ERROR CLASS><LocalDate> +val dateChanges: <ERROR CLASS><LocalDateTime> @@ -149,6 +155,12 @@ in the UI somewhere.

    +networkSendManuallyPumped + +val networkSendManuallyPumped: Boolean + + + notary val notary: SimulatedNode @@ -191,15 +203,15 @@ in the UI somewhere.

    -linkConsensus +showConsensusFor -fun linkConsensus(nodes: Collection<SimulatedNode>, protocol: ProtocolLogic<*>): Unit +fun showConsensusFor(nodes: List<SimulatedNode>): Unit -linkProtocolProgress +showProgressFor -fun linkProtocolProgress(node: SimulatedNode, protocol: ProtocolLogic<*>): Unit +fun showProgressFor(nodes: List<SimulatedNode>): Unit @@ -219,7 +231,7 @@ network bringup has been simulated.

    startTradingCircle -fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc +fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc each time the returned future completes.

    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/iterate.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/iterate.html index 5be053eaee..6595b0b202 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/iterate.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/iterate.html @@ -16,8 +16,8 @@ interesting happening, or control the precise speed at which things operate (bey is a useful way to do things.



    -Return
    -the message that was processed, or null if no node accepted a message in this round.
    +

    Return
    +the message that was processed, or null if no node accepted a message in this round.



    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/network-send-manually-pumped.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/network-send-manually-pumped.html new file mode 100644 index 0000000000..167e7945c3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/network-send-manually-pumped.html @@ -0,0 +1,15 @@ + + +Simulation.networkSendManuallyPumped - + + + +com.r3corda.node.internal.testing / Simulation / networkSendManuallyPumped
    +
    +

    networkSendManuallyPumped

    + +val networkSendManuallyPumped: Boolean
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-consensus-for.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-consensus-for.html new file mode 100644 index 0000000000..eb090e7bf1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-consensus-for.html @@ -0,0 +1,15 @@ + + +Simulation.showConsensusFor - + + + +com.r3corda.node.internal.testing / Simulation / showConsensusFor
    +
    +

    showConsensusFor

    + +protected fun showConsensusFor(nodes: List<SimulatedNode>): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-progress-for.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-progress-for.html new file mode 100644 index 0000000000..6c8ab4506a --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/show-progress-for.html @@ -0,0 +1,15 @@ + + +Simulation.showProgressFor - + + + +com.r3corda.node.internal.testing / Simulation / showProgressFor
    +
    +

    showProgressFor

    + +protected fun showProgressFor(nodes: List<SimulatedNode>): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/start-trading-circle.html b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/start-trading-circle.html index ce81ff4cac..223b6e5e3f 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/start-trading-circle.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-simulation/start-trading-circle.html @@ -7,8 +7,8 @@ com.r3corda.node.internal.testing / Simulation / startTradingCircle

    startTradingCircle

    - -fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit
    + +fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc each time the returned future completes.


    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/advance-by.html b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/advance-by.html index 67d4e2f6f8..194076736f 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/advance-by.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/advance-by.html @@ -8,7 +8,8 @@

    advanceBy

    -fun advanceBy(duration: Duration): Boolean
    +fun advanceBy(duration: Duration): Unit
    +

    Advance this Clock by the specified Duration for testing purposes.



    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/index.html index 74363a5e22..10720346a0 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/index.html @@ -7,7 +7,7 @@ com.r3corda.node.internal.testing / TestClock

    TestClock

    -class TestClock : MutableClock
    +class TestClock : MutableClock, SerializeAsToken

    A Clock that can have the time advanced for use in testing



    @@ -49,7 +49,8 @@ advanceBy -fun advanceBy(duration: Duration): Boolean +fun advanceBy(duration: Duration): Unit

    Advance this Clock by the specified Duration for testing purposes.

    + @@ -65,9 +66,22 @@ +setTo + +fun setTo(newInstant: Instant): Unit

    Move this Clock to the specified Instant for testing purposes.

    + + + + +toToken + +fun toToken(context: SerializeAsTokenContext): SerializationToken + + + withZone -fun withZone(zone: ZoneId): Clock +fun withZone(zone: ZoneId): Clock diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/set-to.html b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/set-to.html new file mode 100644 index 0000000000..a32ac32d5e --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/set-to.html @@ -0,0 +1,19 @@ + + +TestClock.setTo - + + + +com.r3corda.node.internal.testing / TestClock / setTo
    +
    +

    setTo

    + +fun setTo(newInstant: Instant): Unit
    +

    Move this Clock to the specified Instant for testing purposes.

    +

    This will only be approximate due to the time ticking away, but will be some time shortly after the requested Instant.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/to-token.html b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/to-token.html new file mode 100644 index 0000000000..a77b6817cd --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/to-token.html @@ -0,0 +1,16 @@ + + +TestClock.toToken - + + + +com.r3corda.node.internal.testing / TestClock / toToken
    +
    +

    toToken

    + +fun toToken(context: SerializeAsTokenContext): SerializationToken
    +Overrides SerializeAsToken.toToken
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/with-zone.html b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/with-zone.html index 1a62abe9f0..17eb640a5c 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/with-zone.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-test-clock/with-zone.html @@ -8,7 +8,9 @@

    withZone

    -fun withZone(zone: ZoneId): Clock
    +fun withZone(zone: ZoneId): Clock
    +Deprecated: Do not use this. Instead seek to use ZonedDateTime methods.
    +


    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/-trade-simulation/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/-trade-simulation/index.html index a3ac6159bf..cf9e1baae5 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/-trade-simulation/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/-trade-simulation/index.html @@ -54,9 +54,15 @@ then B and C trade with each other, then C and A etc).

    -currentDay +clocks -var currentDay: LocalDate

    The current simulated date. By default this never changes. If you want it to change, you should do so from +val clocks: <ERROR CLASS> + + + +currentDateAndTime + +var currentDateAndTime: LocalDateTime

    The current simulated date. By default this never changes. If you want it to change, you should do so from within your overridden iterate call. Changes in the current day surface in the dateChanges observable.

    @@ -64,7 +70,7 @@ within your overridden iterate call. C dateChanges -val dateChanges: <ERROR CLASS><LocalDate> +val dateChanges: <ERROR CLASS><LocalDateTime> @@ -106,6 +112,12 @@ in the UI somewhere.

    +networkSendManuallyPumped + +val networkSendManuallyPumped: Boolean + + + notary val notary: SimulatedNode @@ -161,15 +173,15 @@ network bringup has been simulated.

    -linkConsensus +showConsensusFor -fun linkConsensus(nodes: Collection<SimulatedNode>, protocol: ProtocolLogic<*>): Unit +fun showConsensusFor(nodes: List<SimulatedNode>): Unit -linkProtocolProgress +showProgressFor -fun linkProtocolProgress(node: SimulatedNode, protocol: ProtocolLogic<*>): Unit +fun showProgressFor(nodes: List<SimulatedNode>): Unit @@ -181,7 +193,7 @@ network bringup has been simulated.

    startTradingCircle -fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc +fun startTradingCircle(tradeBetween: (Int, Int) -> <ERROR CLASS><out <ERROR CLASS>>): Unit

    Given a function that returns a future, iterates that function with arguments like (0, 1), (1, 2), (2, 3) etc each time the returned future completes.

    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/index.html index 11f3b82dd1..5dbb825bd8 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/index.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/index.html @@ -36,7 +36,7 @@ Components that do IO are either swapped out for mocks, or pointed to a TestClock -class TestClock : MutableClock

    A Clock that can have the time advanced for use in testing

    +class TestClock : MutableClock, SerializeAsToken

    A Clock that can have the time advanced for use in testing

    @@ -47,11 +47,16 @@ Components that do IO are either swapped out for mocks, or pointed to a + + +

    Extensions for External Classes

    + + +kotlin.collections.Iterable +
    -WalletFiller -object WalletFiller
    @@ -62,13 +67,19 @@ then B and C trade with each other, then C and A etc).

    issueInvalidState -fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef +fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> + + + +issueMultiPartyState + +fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<MultiOwnerState> issueState -fun issueState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef +fun issueState(node: AbstractNode): StateAndRef<*> diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/issue-invalid-state.html b/docs/build/html/api/com.r3corda.node.internal.testing/issue-invalid-state.html index 972f29cba4..2226b480e0 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/issue-invalid-state.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/issue-invalid-state.html @@ -8,7 +8,7 @@

    issueInvalidState

    -fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef
    +fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*>


    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/issue-multi-party-state.html b/docs/build/html/api/com.r3corda.node.internal.testing/issue-multi-party-state.html new file mode 100644 index 0000000000..d804ff71e4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/issue-multi-party-state.html @@ -0,0 +1,15 @@ + + +issueMultiPartyState - + + + +com.r3corda.node.internal.testing / issueMultiPartyState
    +
    +

    issueMultiPartyState

    + +fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<MultiOwnerState>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/issue-state.html b/docs/build/html/api/com.r3corda.node.internal.testing/issue-state.html index 7671595a78..4c38be0cae 100644 --- a/docs/build/html/api/com.r3corda.node.internal.testing/issue-state.html +++ b/docs/build/html/api/com.r3corda.node.internal.testing/issue-state.html @@ -7,8 +7,8 @@ com.r3corda.node.internal.testing / issueState

    issueState

    - -fun issueState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef
    + +fun issueState(node: AbstractNode): StateAndRef<*>


    diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/index.html b/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/index.html new file mode 100644 index 0000000000..db9b7c5779 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/index.html @@ -0,0 +1,23 @@ + + +com.r3corda.node.internal.testing.kotlin.collections.Iterable - + + + +com.r3corda.node.internal.testing / kotlin.collections.Iterable
    +
    +

    Extensions for kotlin.collections.Iterable

    + + + + + + + +
    +setTo +fun Iterable<TestClock>.setTo(instant: Instant): <ERROR CLASS>

    A helper method to set several TestClocks to approximately the same time. The clocks may drift by the time it +takes for each TestClock to have its time set and any observers to execute.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/set-to.html b/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/set-to.html new file mode 100644 index 0000000000..6a29e63fe4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal.testing/kotlin.collections.-iterable/set-to.html @@ -0,0 +1,17 @@ + + +setTo - + + + +com.r3corda.node.internal.testing / kotlin.collections.Iterable / setTo
    +
    +

    setTo

    + +fun Iterable<TestClock>.setTo(instant: Instant): <ERROR CLASS>
    +

    A helper method to set several TestClocks to approximately the same time. The clocks may drift by the time it +takes for each TestClock to have its time set and any observers to execute.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-states.html b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-states.html index 780dc42f0d..d6d5319252 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-states.html +++ b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-states.html @@ -8,7 +8,7 @@

    fetchStates

    -fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
    +fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?>
    Overrides APIServer.fetchStates


    diff --git a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-transactions.html b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-transactions.html index bd87ee46d3..aacea823fa 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-transactions.html +++ b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/fetch-transactions.html @@ -14,8 +14,8 @@ Overrides txs - The hashes (from StateRef.txhash returned from queryStates) you would like full transactions for.
    -Return
    -null values indicate missing transactions from the requested list.
    +

    Return
    +null values indicate missing transactions from the requested list.



    diff --git a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/index.html b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/index.html index 6ae60245ef..c1c3eab456 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/index.html +++ b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/index.html @@ -63,7 +63,7 @@ successful, otherwise exception is thrown.

    fetchStates -fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?> +fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?> @@ -109,6 +109,13 @@ to avoid calling fetchLedgerTransactions() many times.

    fun serverTime(): LocalDateTime

    Report current UTC time as understood by the platform.

    + + +status + +fun status(): <ERROR CLASS>

    Report whether this node is started up or not

    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/query-states.html b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/query-states.html index d2955835c7..6125cc0208 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/query-states.html +++ b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/query-states.html @@ -16,8 +16,8 @@ to avoid calling fetchLedgerTransactions() many times.

    Parameters

    query - Some "where clause" like expression.
    -Return
    -Zero or more matching States.
    +

    Return
    +Zero or more matching States.



    diff --git a/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/status.html b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/status.html new file mode 100644 index 0000000000..0d79666efa --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-a-p-i-server-impl/status.html @@ -0,0 +1,17 @@ + + +APIServerImpl.status - + + + +com.r3corda.node.internal / APIServerImpl / status
    +
    +

    status

    + +fun status(): <ERROR CLASS>
    +Overrides APIServer.status
    +

    Report whether this node is started up or not

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/create-node-dir.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/create-node-dir.html new file mode 100644 index 0000000000..9b4a99bb51 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/create-node-dir.html @@ -0,0 +1,15 @@ + + +AbstractNode.createNodeDir - + + + +com.r3corda.node.internal / AbstractNode / createNodeDir
    +
    +

    createNodeDir

    + +protected fun createNodeDir(): Unit
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/generate-key-pair.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/generate-key-pair.html index 8a8b4fd79e..202dc93f49 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/generate-key-pair.html +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/generate-key-pair.html @@ -8,7 +8,7 @@

    generateKeyPair

    -protected open fun generateKeyPair(): KeyPair
    +protected open fun generateKeyPair(): <ERROR CLASS>


    diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/index.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/index.html index 7199da99cb..ba6f518de8 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/index.html +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/index.html @@ -145,6 +145,12 @@ I/O), or a mock implementation suitable for unit test environments.

    +scheduler + +lateinit var scheduler: SchedulerService + + + serverThread abstract val serverThread: AffinityExecutor @@ -178,7 +184,7 @@ I/O), or a mock implementation suitable for unit test environments.

    storage -lateinit var storage: StorageService +lateinit var storage: TxWritableStorageService @@ -199,6 +205,12 @@ I/O), or a mock implementation suitable for unit test environments.

    +createNodeDir + +fun createNodeDir(): Unit + + + findMyLocation open fun findMyLocation(): PhysicalLocation? @@ -207,13 +219,13 @@ I/O), or a mock implementation suitable for unit test environments.

    generateKeyPair -open fun generateKeyPair(): KeyPair +open fun generateKeyPair(): <ERROR CLASS> initialiseStorageService -open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage> +open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage> @@ -260,6 +272,13 @@ I/O), or a mock implementation suitable for unit test environments.

    +setup + +open fun setup(): AbstractNode

    Run any tasks that are needed to ensure the node is in a correct state before running start()

    + + + + start open fun start(): AbstractNode diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/initialise-storage-service.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/initialise-storage-service.html index a5a05dc9f8..cc979b8276 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/initialise-storage-service.html +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/initialise-storage-service.html @@ -8,7 +8,7 @@

    initialiseStorageService

    -protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage>
    +protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage>


    diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/scheduler.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/scheduler.html new file mode 100644 index 0000000000..76e0cf73ff --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/scheduler.html @@ -0,0 +1,15 @@ + + +AbstractNode.scheduler - + + + +com.r3corda.node.internal / AbstractNode / scheduler
    +
    +

    scheduler

    + +lateinit var scheduler: SchedulerService
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/setup.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/setup.html new file mode 100644 index 0000000000..51fa9b4bfb --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/setup.html @@ -0,0 +1,16 @@ + + +AbstractNode.setup - + + + +com.r3corda.node.internal / AbstractNode / setup
    +
    +

    setup

    + +open fun setup(): AbstractNode
    +

    Run any tasks that are needed to ensure the node is in a correct state before running start()

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/storage.html b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/storage.html index 9a1fb09728..cc51e1fc01 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-abstract-node/storage.html +++ b/docs/build/html/api/com.r3corda.node.internal/-abstract-node/storage.html @@ -8,7 +8,7 @@

    storage

    -lateinit var storage: StorageService
    +lateinit var storage: TxWritableStorageService


    diff --git a/docs/build/html/api/com.r3corda.node.internal/-node/-init-.html b/docs/build/html/api/com.r3corda.node.internal/-node/-init-.html index 37981a39c8..328efc2d5a 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-node/-init-.html +++ b/docs/build/html/api/com.r3corda.node.internal/-node/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.internal / Node / <init>

    <init>

    -Node(dir: Path, p2pAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())
    +Node(dir: Path, p2pAddr: <ERROR CLASS>, webServerAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())

    A Node manages a standalone server that takes part in the P2P network. It creates the services found in ServiceHub, loads important data off disk and starts listening for connections.

    Parameters

    diff --git a/docs/build/html/api/com.r3corda.node.internal/-node/index.html b/docs/build/html/api/com.r3corda.node.internal/-node/index.html index aec969fc20..92ab822155 100644 --- a/docs/build/html/api/com.r3corda.node.internal/-node/index.html +++ b/docs/build/html/api/com.r3corda.node.internal/-node/index.html @@ -45,7 +45,7 @@ Listed clientAPI classes are assumed to have to take a single APIServer construc <init> -Node(dir: Path, p2pAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())

    A Node manages a standalone server that takes part in the P2P network. It creates the services found in ServiceHub, +Node(dir: Path, p2pAddr: <ERROR CLASS>, webServerAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())

    A Node manages a standalone server that takes part in the P2P network. It creates the services found in ServiceHub, loads important data off disk and starts listening for connections.

    @@ -84,6 +84,12 @@ loads important data off disk and starts listening for connections.

    lateinit var webServer: <ERROR CLASS> + + +webServerAddr + +val webServerAddr: <ERROR CLASS> +

    Inherited Properties

    @@ -200,6 +206,12 @@ loads important data off disk and starts listening for connections.

    +scheduler + +lateinit var scheduler: SchedulerService + + + services val services: ServiceHubInternal @@ -227,7 +239,7 @@ loads important data off disk and starts listening for connections.

    storage -lateinit var storage: StorageService +lateinit var storage: TxWritableStorageService @@ -248,6 +260,13 @@ loads important data off disk and starts listening for connections.

    +setup + +fun setup(): Node

    Run any tasks that are needed to ensure the node is in a correct state before running start()

    + + + + start fun start(): Node @@ -277,6 +296,12 @@ loads important data off disk and starts listening for connections.

    +createNodeDir + +fun createNodeDir(): Unit + + + findMyLocation open fun findMyLocation(): PhysicalLocation? @@ -285,13 +310,13 @@ loads important data off disk and starts listening for connections.

    generateKeyPair -open fun generateKeyPair(): KeyPair +open fun generateKeyPair(): <ERROR CLASS> initialiseStorageService -open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage> +open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage> diff --git a/docs/build/html/api/com.r3corda.node.internal/-node/setup.html b/docs/build/html/api/com.r3corda.node.internal/-node/setup.html new file mode 100644 index 0000000000..d558159ff9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-node/setup.html @@ -0,0 +1,17 @@ + + +Node.setup - + + + +com.r3corda.node.internal / Node / setup
    +
    +

    setup

    + +fun setup(): Node
    +Overrides AbstractNode.setup
    +

    Run any tasks that are needed to ensure the node is in a correct state before running start()

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.internal/-node/web-server-addr.html b/docs/build/html/api/com.r3corda.node.internal/-node/web-server-addr.html new file mode 100644 index 0000000000..1bdd912829 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.internal/-node/web-server-addr.html @@ -0,0 +1,15 @@ + + +Node.webServerAddr - + + + +com.r3corda.node.internal / Node / webServerAddr
    +
    +

    webServerAddr

    + +val webServerAddr: <ERROR CLASS>
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/-init-.html index a4fbadae50..3e66ba201a 100644 --- a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.api / AbstractNodeService / <init>

    <init>

    -AbstractNodeService(net: MessagingService)
    +AbstractNodeService(net: MessagingService, networkMapCache: NetworkMapCache)

    Abstract superclass for services that a node can host, which provides helper functions.



    diff --git a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/add-message-handler.html b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/add-message-handler.html index 2f5176e9be..5b1fa9b396 100644 --- a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/add-message-handler.html +++ b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/add-message-handler.html @@ -8,30 +8,32 @@

    addMessageHandler

    -protected inline fun <reified Q : AbstractRequestMessage, reified R : Any> addMessageHandler(topic: String, crossinline handler: (Q) -> R, crossinline exceptionConsumer: (Message, Exception) -> Unit): Unit
    +protected inline fun <reified Q : ServiceRequestMessage, reified R : Any> addMessageHandler(topic: String, crossinline handler: (Q) -> R, crossinline exceptionConsumer: (Message, Exception) -> Unit): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

    +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    Parameters

    topic - the topic, without the default session ID postfix (".0)

    -handler - a function to handle the deserialised request and return a response
    +handler - a function to handle the deserialised request and return an optional response (if return type not Unit)

    exceptionConsumer - a function to which any thrown exception is passed.


    -protected inline fun <reified Q : AbstractRequestMessage, reified R : Any> addMessageHandler(topic: String, crossinline handler: (Q) -> R): Unit
    +protected inline fun <reified Q : ServiceRequestMessage, reified R : Any> addMessageHandler(topic: String, crossinline handler: (Q) -> R): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

    +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    Parameters

    topic - the topic, without the default session ID postfix (".0)

    -handler - a function to handle the deserialised request and return a response
    +handler - a function to handle the deserialised request and return an optional response (if return type not Unit)


    diff --git a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/index.html b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/index.html index 1af1aaaf89..c643e4a666 100644 --- a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.api / AbstractNodeService

    AbstractNodeService

    -abstract class AbstractNodeService
    +abstract class AbstractNodeService : SingletonSerializeAsToken

    Abstract superclass for services that a node can host, which provides helper functions.



    @@ -18,7 +18,7 @@ <init> -AbstractNodeService(net: MessagingService)

    Abstract superclass for services that a node can host, which provides helper functions.

    +AbstractNodeService(net: MessagingService, networkMapCache: NetworkMapCache)

    Abstract superclass for services that a node can host, which provides helper functions.

    @@ -32,6 +32,12 @@ val net: MessagingService + + +networkMapCache + +val networkMapCache: NetworkMapCache +

    Functions

    @@ -41,14 +47,27 @@ addMessageHandler -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

    -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

    +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    +

    Inherited Functions

    + + + + + + + +
    +toToken +open fun toToken(context: SerializeAsTokenContext): SerializationToken

    Inheritors

    @@ -68,6 +87,14 @@ glue that sits between the network layer and the database layer.

    + + + + + + + + @@ -68,6 +91,20 @@
    +NotaryChangeService +class NotaryChangeService : AbstractNodeService

    A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

    +
    NotaryService abstract class NotaryService : AbstractNodeService

    A Notary service acts as the final signer of a transaction ensuring two things:

    diff --git a/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/network-map-cache.html b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/network-map-cache.html new file mode 100644 index 0000000000..aa82cd1246 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.api/-abstract-node-service/network-map-cache.html @@ -0,0 +1,15 @@ + + +AbstractNodeService.networkMapCache - + + + +com.r3corda.node.services.api / AbstractNodeService / networkMapCache
    +
    +

    networkMapCache

    + +val networkMapCache: NetworkMapCache
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/-init-.html b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/-init-.html new file mode 100644 index 0000000000..949e8c0dda --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/-init-.html @@ -0,0 +1,14 @@ + + +ServiceHubInternal.<init> - + + + +com.r3corda.node.services.api / ServiceHubInternal / <init>
    +
    +

    <init>

    +ServiceHubInternal()
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/index.html b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/index.html index d82d7660e8..87764128a3 100644 --- a/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/index.html +++ b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/index.html @@ -7,9 +7,20 @@ com.r3corda.node.services.api / ServiceHubInternal

    ServiceHubInternal

    -interface ServiceHubInternal : ServiceHub
    +abstract class ServiceHubInternal : ServiceHub


    +

    Constructors

    + + + + + + + +
    +<init> +ServiceHubInternal()

    Properties

    @@ -19,6 +30,12 @@ + + + +
    abstract val monitoringService: MonitoringService
    +protocolLogicRefFactory +abstract val protocolLogicRefFactory: ProtocolLogicRefFactory

    Inherited Properties

    @@ -56,6 +73,12 @@
    +schedulerService +abstract val schedulerService: SchedulerService
    storageService abstract val storageService: StorageService
    +

    Functions

    + + + + + + + +
    +startProtocol +abstract fun <T> startProtocol(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>

    TODO: borrowing this method from service manager work in another branch. Its required to avoid circular dependency +between SMM and the scheduler. That particular problem should also be resolved by the service manager work +itself, at which point this method would not be needed (by the scheduler)

    +

    Inherited Functions

    @@ -75,14 +112,16 @@ @@ -97,5 +136,18 @@ transaction. If no exception is thrown, the transaction is valid.

    loadState -open fun loadState(stateRef: StateRef): ContractState

    Given a StateRef loads the referenced transaction and looks up the specified output ContractState

    +open fun loadState(stateRef: StateRef): TransactionState<*>

    Given a StateRef loads the referenced transaction and looks up the specified output ContractState

    recordTransactions -open fun recordTransactions(txs: List<SignedTransaction>): Unit

    Given a list of SignedTransactions, writes them to the local storage for validated transactions and then +abstract fun recordTransactions(txs: Iterable<SignedTransaction>): Unit

    Given a list of SignedTransactions, writes them to the local storage for validated transactions and then +sends them to the wallet for further processing.

    +open fun recordTransactions(vararg txs: SignedTransaction): <ERROR CLASS>

    Given some SignedTransactions, writes them to the local storage for validated transactions and then sends them to the wallet for further processing.

    +

    Extension Functions

    + + + + + + + +
    +fillWithSomeTestCash +fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>, notary: Party = DUMMY_NOTARY, atLeastThisManyStates: Int = 3, atMostThisManyStates: Int = 10, rng: Random = Random(), ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 0 }))): Wallet

    Creates a random set of between (by default) 3 and 10 cash states that add up to the given amount and adds them +to the wallet. This is intended for unit tests.

    +
    diff --git a/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/protocol-logic-ref-factory.html b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/protocol-logic-ref-factory.html new file mode 100644 index 0000000000..ac451032a4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/protocol-logic-ref-factory.html @@ -0,0 +1,15 @@ + + +ServiceHubInternal.protocolLogicRefFactory - + + + +com.r3corda.node.services.api / ServiceHubInternal / protocolLogicRefFactory
    +
    +

    protocolLogicRefFactory

    + +abstract val protocolLogicRefFactory: ProtocolLogicRefFactory
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/start-protocol.html b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/start-protocol.html new file mode 100644 index 0000000000..b91f456d66 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.api/-service-hub-internal/start-protocol.html @@ -0,0 +1,18 @@ + + +ServiceHubInternal.startProtocol - + + + +com.r3corda.node.services.api / ServiceHubInternal / startProtocol
    +
    +

    startProtocol

    + +abstract fun <T> startProtocol(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>
    +

    TODO: borrowing this method from service manager work in another branch. Its required to avoid circular dependency +between SMM and the scheduler. That particular problem should also be resolved by the service manager work +itself, at which point this method would not be needed (by the scheduler)

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.api/index.html b/docs/build/html/api/com.r3corda.node.services.api/index.html index fc4a4ac1dd..936dc89ec4 100644 --- a/docs/build/html/api/com.r3corda.node.services.api/index.html +++ b/docs/build/html/api/com.r3corda.node.services.api/index.html @@ -14,7 +14,7 @@ AbstractNodeService -abstract class AbstractNodeService

    Abstract superclass for services that a node can host, which provides helper functions.

    +abstract class AbstractNodeService : SingletonSerializeAsToken

    Abstract superclass for services that a node can host, which provides helper functions.

    @@ -56,7 +56,7 @@ This is not an interface because it is too lightweight to bother mocking out.

    ServiceHubInternal -interface ServiceHubInternal : ServiceHub +abstract class ServiceHubInternal : ServiceHub diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/-init-.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/-init-.html index 79771ec824..b63c80734f 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.clientapi / NodeInterestRates / Oracle / <init>

    <init>

    -Oracle(identity: Party, signingKey: KeyPair)
    +Oracle(identity: Party, signingKey: KeyPair, clock: Clock)

    An implementation of an interest rate fix oracle which is given data in a simple string format.

    The oracle will try to interpolate the missing value of a tenor for the given fix name and date.


    diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/clock.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/clock.html new file mode 100644 index 0000000000..aebde2d534 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/clock.html @@ -0,0 +1,15 @@ + + +NodeInterestRates.Oracle.clock - + + + +com.r3corda.node.services.clientapi / NodeInterestRates / Oracle / clock
    +
    +

    clock

    + +val clock: Clock
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/index.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/index.html index e44b0c9a5b..55f4f285e2 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/index.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/index.html @@ -21,7 +21,7 @@ <init> -Oracle(identity: Party, signingKey: KeyPair)

    An implementation of an interest rate fix oracle which is given data in a simple string format.

    +Oracle(identity: Party, signingKey: KeyPair, clock: Clock)

    An implementation of an interest rate fix oracle which is given data in a simple string format.

    @@ -31,6 +31,12 @@ +clock + +val clock: Clock + + + identity val identity: Party @@ -50,7 +56,10 @@ query -fun query(queries: List<FixOf>): List<Fix> +fun query(queries: List<FixOf>, deadline: Instant): List<Fix>

    This method will now wait until the given deadline if the fix for the given FixOf is not immediately +available. To implement this, readWithDeadline will loop if the deadline is not reached and we throw +UnknownFix as it implements RetryableException which has special meaning to this function.

    + diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/query.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/query.html index 904322ccc3..93164e93b0 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/query.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-oracle/query.html @@ -7,8 +7,11 @@ com.r3corda.node.services.clientapi / NodeInterestRates / Oracle / query

    query

    - -fun query(queries: List<FixOf>): List<Fix>
    + +fun query(queries: List<FixOf>, deadline: Instant): List<Fix>
    +

    This method will now wait until the given deadline if the fix for the given FixOf is not immediately +available. To implement this, readWithDeadline will loop if the deadline is not reached and we throw +UnknownFix as it implements RetryableException which has special meaning to this function.



    diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-service/index.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-service/index.html index 9bea4ae0d0..a05c3ad822 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-service/index.html @@ -63,6 +63,12 @@ val net: MessagingService + + +networkMapCache + +val networkMapCache: NetworkMapCache +

    Functions

    @@ -85,10 +91,12 @@ back to the user in the response.

    addMessageHandler -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

    -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

    +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

    Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

    diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-unknown-fix/index.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-unknown-fix/index.html index d0d9c30710..dd0b21c140 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-unknown-fix/index.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/-unknown-fix/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.clientapi / NodeInterestRates / UnknownFix

    UnknownFix

    -class UnknownFix : Exception
    +class UnknownFix : RetryableException


    Constructors

    @@ -32,16 +32,5 @@ -

    Functions

    - - - - - - - -
    -toString -fun toString(): String
    diff --git a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/index.html b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/index.html index 0cf4832dcd..e0c26024ce 100644 --- a/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/index.html +++ b/docs/build/html/api/com.r3corda.node.services.clientapi/-node-interest-rates/index.html @@ -65,7 +65,7 @@ Interpolates missing values using the provided interpolation mechanism.

    UnknownFix -class UnknownFix : Exception +class UnknownFix : RetryableException diff --git a/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/-init-.html new file mode 100644 index 0000000000..fd2d6c6066 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/-init-.html @@ -0,0 +1,35 @@ + + +NodeSchedulerService.<init> - + + + +com.r3corda.node.services.events / NodeSchedulerService / <init>
    +
    +

    <init>

    +NodeSchedulerService(services: ServiceHubInternal, protocolLogicRefFactory: ProtocolLogicRefFactory = ProtocolLogicRefFactory(), schedulerTimerExecutor: Executor = Executors.newSingleThreadExecutor())
    +

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    +

    This will observe transactions as they are stored and schedule and unschedule activities based on the States consumed +or produced.

    +

    TODO: Needs extensive support from persistence and protocol frameworks to be truly reliable and atomic.

    +

    Currently does not provide any system state other than the ContractState so the expectation is that a transaction +is the outcome of the activity in order to schedule another activity. Once we have implemented more persistence +in the nodes, maybe we can consider multiple activities and whether the activities have been completed or not, +but that starts to sound a lot like off-ledger state.

    +
    +
    +

    Parameters

    + +services - Core node services.
    +
    + +protocolLogicRefFactory - Factory for restoring ProtocolLogic instances from references.
    +
    + +schedulerTimerExecutor - The executor the scheduler blocks on waiting for the clock to advance to the next +activity. Only replace this for unit testing purposes. This is not the executor the ProtocolLogic is launched on.
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/index.html b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/index.html new file mode 100644 index 0000000000..bf47a14e04 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/index.html @@ -0,0 +1,78 @@ + + +NodeSchedulerService - + + + +com.r3corda.node.services.events / NodeSchedulerService
    +
    +

    NodeSchedulerService

    +class NodeSchedulerService : SchedulerService, SingletonSerializeAsToken
    +

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    +

    This will observe transactions as they are stored and schedule and unschedule activities based on the States consumed +or produced.

    +

    TODO: Needs extensive support from persistence and protocol frameworks to be truly reliable and atomic.

    +

    Currently does not provide any system state other than the ContractState so the expectation is that a transaction +is the outcome of the activity in order to schedule another activity. Once we have implemented more persistence +in the nodes, maybe we can consider multiple activities and whether the activities have been completed or not, +but that starts to sound a lot like off-ledger state.

    +
    +
    +

    Parameters

    + +services - Core node services.
    +
    + +protocolLogicRefFactory - Factory for restoring ProtocolLogic instances from references.
    +
    + +schedulerTimerExecutor - The executor the scheduler blocks on waiting for the clock to advance to the next +activity. Only replace this for unit testing purposes. This is not the executor the ProtocolLogic is launched on.
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +NodeSchedulerService(services: ServiceHubInternal, protocolLogicRefFactory: ProtocolLogicRefFactory = ProtocolLogicRefFactory(), schedulerTimerExecutor: Executor = Executors.newSingleThreadExecutor())

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    +
    +

    Functions

    + + + + + + + + + + + +
    +scheduleStateActivity +fun scheduleStateActivity(action: ScheduledStateRef): Unit

    Schedule a new activity for a TX output, probably because it was just produced.

    +
    +unscheduleStateActivity +fun unscheduleStateActivity(ref: StateRef): Unit

    Unschedule all activity for a TX output, probably because it was consumed.

    +
    +

    Inherited Functions

    + + + + + + + +
    +toToken +open fun toToken(context: SerializeAsTokenContext): SerializationToken
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/schedule-state-activity.html b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/schedule-state-activity.html new file mode 100644 index 0000000000..de952a17a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/schedule-state-activity.html @@ -0,0 +1,21 @@ + + +NodeSchedulerService.scheduleStateActivity - + + + +com.r3corda.node.services.events / NodeSchedulerService / scheduleStateActivity
    +
    +

    scheduleStateActivity

    + +fun scheduleStateActivity(action: ScheduledStateRef): Unit
    +Overrides SchedulerService.scheduleStateActivity
    +

    Schedule a new activity for a TX output, probably because it was just produced.

    +

    Only one activity can be scheduled for a particular StateRef at any one time. Scheduling a ScheduledStateRef +replaces any previously scheduled ScheduledStateRef for any one StateRef.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/unschedule-state-activity.html b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/unschedule-state-activity.html new file mode 100644 index 0000000000..51c2dfd287 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-node-scheduler-service/unschedule-state-activity.html @@ -0,0 +1,17 @@ + + +NodeSchedulerService.unscheduleStateActivity - + + + +com.r3corda.node.services.events / NodeSchedulerService / unscheduleStateActivity
    +
    +

    unscheduleStateActivity

    + +fun unscheduleStateActivity(ref: StateRef): Unit
    +Overrides SchedulerService.unscheduleStateActivity
    +

    Unschedule all activity for a TX output, probably because it was consumed.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/-init-.html b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/-init-.html new file mode 100644 index 0000000000..9b35e03e46 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/-init-.html @@ -0,0 +1,16 @@ + + +ScheduledActivityObserver.<init> - + + + +com.r3corda.node.services.events / ScheduledActivityObserver / <init>
    +
    +

    <init>

    +ScheduledActivityObserver(services: ServiceHubInternal)
    +

    This observes the wallet and schedules and unschedules activities appropriately based on state production and +consumption.

    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/index.html b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/index.html new file mode 100644 index 0000000000..158ba7c287 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/index.html @@ -0,0 +1,40 @@ + + +ScheduledActivityObserver - + + + +com.r3corda.node.services.events / ScheduledActivityObserver
    +
    +

    ScheduledActivityObserver

    +class ScheduledActivityObserver
    +

    This observes the wallet and schedules and unschedules activities appropriately based on state production and +consumption.

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +ScheduledActivityObserver(services: ServiceHubInternal)

    This observes the wallet and schedules and unschedules activities appropriately based on state production and +consumption.

    +
    +

    Properties

    + + + + + + + +
    +services +val services: ServiceHubInternal
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/services.html b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/services.html new file mode 100644 index 0000000000..4dd01b933f --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/-scheduled-activity-observer/services.html @@ -0,0 +1,15 @@ + + +ScheduledActivityObserver.services - + + + +com.r3corda.node.services.events / ScheduledActivityObserver / services
    +
    +

    services

    + +val services: ServiceHubInternal
    +
    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.events/index.html b/docs/build/html/api/com.r3corda.node.services.events/index.html new file mode 100644 index 0000000000..fda2bfe737 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.events/index.html @@ -0,0 +1,32 @@ + + +com.r3corda.node.services.events - + + + +com.r3corda.node.services.events
    +
    +

    Package com.r3corda.node.services.events

    +

    Types

    + + + + + + + + + + + +
    +NodeSchedulerService +class NodeSchedulerService : SchedulerService, SingletonSerializeAsToken

    A first pass of a simple SchedulerService that works with MutableClocks for testing, demonstrations and simulations +that also encompasses the Wallet observer for processing transactions.

    +
    +ScheduledActivityObserver +class ScheduledActivityObserver

    This observes the wallet and schedules and unschedules activities appropriately based on state production and +consumption.

    +
    + + diff --git a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/-init-.html index ea707c5e9b..2c48aa30d4 100644 --- a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.keys / E2ETestKeyManagementService / <init>

    <init>

    -E2ETestKeyManagementService()
    +E2ETestKeyManagementService(initialKeys: Set<KeyPair>)

    A simple in-memory KMS that doesnt bother saving keys to disk. A real implementation would:

    • Probably be accessed via the network layer as an internal node service i.e. via a message queue, so it can run on a separate/firewalled service.

      diff --git a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/index.html b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/index.html index 1a8340dafa..93e6aa8d82 100644 --- a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/index.html @@ -26,7 +26,7 @@ on a separate/firewalled service.

      <init> -E2ETestKeyManagementService()

      A simple in-memory KMS that doesnt bother saving keys to disk. A real implementation would:

      +E2ETestKeyManagementService(initialKeys: Set<KeyPair>)

      A simple in-memory KMS that doesnt bother saving keys to disk. A real implementation would:

      diff --git a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/keys.html b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/keys.html index 8e06733bf4..933a5136fc 100644 --- a/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/keys.html +++ b/docs/build/html/api/com.r3corda.node.services.keys/-e2-e-test-key-management-service/keys.html @@ -11,9 +11,9 @@ val keys: Map<PublicKey, PrivateKey>
      Overrides KeyManagementService.keys

      Returns a snapshot of the current pubkey->privkey mapping.

      -Getter
      +

      Getter

      Returns a snapshot of the current pubkey->privkey mapping.

      -
      +



      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/index.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/index.html index 2449904983..10f5e2569a 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/index.html @@ -97,9 +97,9 @@ executor. The topic can be the empty string to match all messages.

      -pump +pumpReceive -fun pump(block: Boolean): MessageTransfer?

      Delivers a single message from the internal queue. If there are no messages waiting to be delivered and block +fun pumpReceive(block: Boolean): MessageTransfer?

      Delivers a single message from the internal queue. If there are no messages waiting to be delivered and block is true, waits until one has been provided on a different thread via send. If block is false, the return result indicates whether a message was delivered or not.

      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/pump-receive.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/pump-receive.html new file mode 100644 index 0000000000..3aa0d40c12 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-in-memory-messaging/pump-receive.html @@ -0,0 +1,20 @@ + + +InMemoryMessagingNetwork.InMemoryMessaging.pumpReceive - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / InMemoryMessaging / pumpReceive
      +
      +

      pumpReceive

      + +fun pumpReceive(block: Boolean): MessageTransfer?
      +

      Delivers a single message from the internal queue. If there are no messages waiting to be delivered and block +is true, waits until one has been provided on a different thread via send. If block is false, the return +result indicates whether a message was delivered or not.

      +

      Return
      +the message that was processed, if any in this round.

      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-init-.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-init-.html index 9080279a32..1c07d02f7b 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.network / InMemoryMessagingNetwork / <init>

      <init>

      -InMemoryMessagingNetwork()
      +InMemoryMessagingNetwork(sendManuallyPumped: Boolean)

      An in-memory network allows you to manufacture InMemoryMessagings for a set of participants. Each InMemoryMessaging maintains a queue of messages it has received, and a background thread that dispatches messages one by one to registered handlers. Alternatively, a messaging system may be manually pumped, in which diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/create-node.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/create-node.html index 31503d5272..5e1cd3199b 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/create-node.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/create-node.html @@ -11,7 +11,7 @@ fun createNode(manuallyPumped: Boolean): <ERROR CLASS><Handle, MessagingServiceBuilder<InMemoryMessaging>>

      Creates a node and returns the new object that identifies its location on the network to senders, and the InMemoryMessaging that the recipient/in-memory node uses to receive messages and send messages itself.

      -

      If manuallyPumped is set to true, then you are expected to call the InMemoryMessaging.pump method on the InMemoryMessaging +

      If manuallyPumped is set to true, then you are expected to call the InMemoryMessaging.pump method on the InMemoryMessaging in order to cause the delivery of a single message, which will occur on the thread of the caller. If set to false then this class will set up a background thread to deliver messages asynchronously, if the handler specifies no executor.

      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/index.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/index.html index d451ad1feb..63d05087ed 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/index.html @@ -60,7 +60,7 @@ when all entities on the network are being simulated in-process.

      <init> -InMemoryMessagingNetwork()

      An in-memory network allows you to manufacture InMemoryMessagings for a set of participants. Each +InMemoryMessagingNetwork(sendManuallyPumped: Boolean)

      An in-memory network allows you to manufacture InMemoryMessagings for a set of participants. Each InMemoryMessaging maintains a queue of messages it has received, and a background thread that dispatches messages one by one to registered handlers. Alternatively, a messaging system may be manually pumped, in which case no thread is created and a caller is expected to force delivery one at a time (this is useful for unit @@ -74,13 +74,6 @@ testing).

      -allMessages - -val allMessages: <ERROR CLASS><MessageTransfer>

      A stream of (sender, message, recipients) triples

      - - - - endpoints val endpoints: List<InMemoryMessaging> @@ -98,6 +91,26 @@ testing).

      var latencyCalculator: LatencyCalculator?

      This can be set to an object which can inject artificial latency between sender/recipient pairs.

      + + +receivedMessages + +val receivedMessages: <ERROR CLASS><MessageTransfer>

      A stream of (sender, message, recipients) triples

      + + + + +sendManuallyPumped + +val sendManuallyPumped: Boolean + + + +sentMessages + +val sentMessages: <ERROR CLASS><MessageTransfer>

      A stream of (sender, message, recipients) triples

      + +

      Functions

      @@ -120,6 +133,18 @@ testing).

      +pumpSend + +fun pumpSend(block: Boolean): MessageTransfer? + + + +pumpSendInternal + +fun pumpSendInternal(transfer: MessageTransfer): Unit + + + stop fun stop(): Unit diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send-internal.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send-internal.html new file mode 100644 index 0000000000..242283b31f --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send-internal.html @@ -0,0 +1,15 @@ + + +InMemoryMessagingNetwork.pumpSendInternal - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / pumpSendInternal
      +
      +

      pumpSendInternal

      + +fun pumpSendInternal(transfer: MessageTransfer): Unit
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send.html new file mode 100644 index 0000000000..441973d30c --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/pump-send.html @@ -0,0 +1,15 @@ + + +InMemoryMessagingNetwork.pumpSend - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / pumpSend
      +
      +

      pumpSend

      + +fun pumpSend(block: Boolean): MessageTransfer?
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/received-messages.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/received-messages.html new file mode 100644 index 0000000000..ae8c94184d --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/received-messages.html @@ -0,0 +1,16 @@ + + +InMemoryMessagingNetwork.receivedMessages - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / receivedMessages
      +
      +

      receivedMessages

      + +val receivedMessages: <ERROR CLASS><MessageTransfer>
      +

      A stream of (sender, message, recipients) triples

      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/send-manually-pumped.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/send-manually-pumped.html new file mode 100644 index 0000000000..de38c759b9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/send-manually-pumped.html @@ -0,0 +1,15 @@ + + +InMemoryMessagingNetwork.sendManuallyPumped - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / sendManuallyPumped
      +
      +

      sendManuallyPumped

      + +val sendManuallyPumped: Boolean
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/sent-messages.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/sent-messages.html new file mode 100644 index 0000000000..ebeec4eb72 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-messaging-network/sent-messages.html @@ -0,0 +1,16 @@ + + +InMemoryMessagingNetwork.sentMessages - + + + +com.r3corda.node.services.network / InMemoryMessagingNetwork / sentMessages
      +
      +

      sentMessages

      + +val sentMessages: <ERROR CLASS><MessageTransfer>
      +

      A stream of (sender, message, recipients) triples

      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/network-map-nodes.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/network-map-nodes.html index c6e118a45f..21c1b4004a 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/network-map-nodes.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/network-map-nodes.html @@ -11,9 +11,9 @@ open val networkMapNodes: List<NodeInfo>
      Overrides NetworkMapCache.networkMapNodes

      A list of nodes that advertise a network map service

      -Getter
      +

      Getter

      A list of nodes that advertise a network map service

      -
      +



      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/notary-nodes.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/notary-nodes.html index bc2ce2c8e5..70690525bf 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/notary-nodes.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/notary-nodes.html @@ -11,9 +11,9 @@ open val notaryNodes: List<NodeInfo>
      Overrides NetworkMapCache.notaryNodes

      A list of nodes that advertise a notary service

      -Getter
      +

      Getter

      A list of nodes that advertise a notary service

      -
      +



      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/party-nodes.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/party-nodes.html index 7e39ee7068..6554afa1c7 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/party-nodes.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/party-nodes.html @@ -11,9 +11,9 @@ open val partyNodes: List<NodeInfo>
      Overrides NetworkMapCache.partyNodes

      A list of all nodes the cache is aware of

      -Getter
      +

      Getter

      A list of all nodes the cache is aware of

      -
      +



      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/rates-oracle-nodes.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/rates-oracle-nodes.html index 0646984d3b..a1508ff82f 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/rates-oracle-nodes.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/rates-oracle-nodes.html @@ -11,9 +11,9 @@ open val ratesOracleNodes: List<NodeInfo>
      Overrides NetworkMapCache.ratesOracleNodes

      A list of nodes that advertise a rates oracle service

      -Getter
      +

      Getter

      A list of nodes that advertise a rates oracle service

      -
      +



      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/regulators.html b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/regulators.html index 6fc21fa0be..69859b6a8f 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/regulators.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-in-memory-network-map-cache/regulators.html @@ -13,11 +13,11 @@ Overrides val net: MessagingService + + +networkMapCache + +val networkMapCache: NetworkMapCache +

      Functions

      @@ -118,10 +124,12 @@ addMessageHandler -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

      -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

      +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

      +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/index.html index 95a08a61a2..c7a0dc1064 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.network / NetworkMapService / FetchMapRequest

      FetchMapRequest

      -class FetchMapRequest : AbstractRequestMessage
      +class FetchMapRequest : NetworkMapRequestMessage


      Constructors

      @@ -32,6 +32,12 @@ +sessionID + +val sessionID: Long + + + subscribe val subscribe: Boolean @@ -43,15 +49,20 @@ -replyTo +replyTo val replyTo: MessageRecipients + + +

      Inherited Functions

      + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      -sessionID -val sessionID: Long?
      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/session-i-d.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/session-i-d.html new file mode 100644 index 0000000000..54a0829282 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-fetch-map-request/session-i-d.html @@ -0,0 +1,16 @@ + + +NetworkMapService.FetchMapRequest.sessionID - + + + +com.r3corda.node.services.network / NetworkMapService / FetchMapRequest / sessionID
      +
      +

      sessionID

      + +val sessionID: Long
      +Overrides ServiceRequestMessage.sessionID
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/-init-.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/-init-.html new file mode 100644 index 0000000000..4bdb9b47d8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/-init-.html @@ -0,0 +1,14 @@ + + +NetworkMapService.NetworkMapRequestMessage.<init> - + + + +com.r3corda.node.services.network / NetworkMapService / NetworkMapRequestMessage / <init>
      +
      +

      <init>

      +NetworkMapRequestMessage(replyTo: MessageRecipients)
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/get-reply-to.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/get-reply-to.html new file mode 100644 index 0000000000..411c03272e --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/get-reply-to.html @@ -0,0 +1,16 @@ + + +NetworkMapService.NetworkMapRequestMessage.getReplyTo - + + + +com.r3corda.node.services.network / NetworkMapService / NetworkMapRequestMessage / getReplyTo
      +
      +

      getReplyTo

      + +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      +Overrides ServiceRequestMessage.getReplyTo
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/index.html new file mode 100644 index 0000000000..fa98395ee8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/index.html @@ -0,0 +1,87 @@ + + +NetworkMapService.NetworkMapRequestMessage - + + + +com.r3corda.node.services.network / NetworkMapService / NetworkMapRequestMessage
      +
      +

      NetworkMapRequestMessage

      +abstract class NetworkMapRequestMessage : ServiceRequestMessage
      +
      +
      +

      Constructors

      + + + + + + + +
      +<init> +NetworkMapRequestMessage(replyTo: MessageRecipients)
      +

      Properties

      + + + + + + + +
      +replyTo +val replyTo: MessageRecipients
      +

      Inherited Properties

      + + + + + + + +
      +sessionID +abstract val sessionID: Long
      +

      Functions

      + + + + + + + +
      +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      +

      Inheritors

      + + + + + + + + + + + + + + + + + + + +
      +FetchMapRequest +class FetchMapRequest : NetworkMapRequestMessage
      +QueryIdentityRequest +class QueryIdentityRequest : NetworkMapRequestMessage
      +RegistrationRequest +class RegistrationRequest : NetworkMapRequestMessage
      +SubscribeRequest +class SubscribeRequest : NetworkMapRequestMessage
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/reply-to.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/reply-to.html new file mode 100644 index 0000000000..8d20583bc8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-network-map-request-message/reply-to.html @@ -0,0 +1,15 @@ + + +NetworkMapService.NetworkMapRequestMessage.replyTo - + + + +com.r3corda.node.services.network / NetworkMapService / NetworkMapRequestMessage / replyTo
      +
      +

      replyTo

      + +val replyTo: MessageRecipients
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/index.html index 36df720f8b..f900946b0f 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.network / NetworkMapService / QueryIdentityRequest

      QueryIdentityRequest

      -class QueryIdentityRequest : AbstractRequestMessage
      +class QueryIdentityRequest : NetworkMapRequestMessage


      Constructors

      @@ -30,6 +30,12 @@ val identity: Party + + +sessionID + +val sessionID: Long +

      Inherited Properties

      @@ -37,15 +43,20 @@ -replyTo +replyTo val replyTo: MessageRecipients + + +

      Inherited Functions

      + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      -sessionID -val sessionID: Long?
      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/session-i-d.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/session-i-d.html new file mode 100644 index 0000000000..76256205ae --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-query-identity-request/session-i-d.html @@ -0,0 +1,16 @@ + + +NetworkMapService.QueryIdentityRequest.sessionID - + + + +com.r3corda.node.services.network / NetworkMapService / QueryIdentityRequest / sessionID
      +
      +

      sessionID

      + +val sessionID: Long
      +Overrides ServiceRequestMessage.sessionID
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/index.html index 5edbe99a3b..e4cfb86148 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.network / NetworkMapService / RegistrationRequest

      RegistrationRequest

      -class RegistrationRequest : AbstractRequestMessage
      +class RegistrationRequest : NetworkMapRequestMessage


      Constructors

      @@ -26,6 +26,12 @@ +sessionID + +val sessionID: Long + + + wireReg val wireReg: WireNodeRegistration @@ -37,15 +43,20 @@ -replyTo +replyTo val replyTo: MessageRecipients + + +

      Inherited Functions

      + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      -sessionID -val sessionID: Long?
      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/session-i-d.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/session-i-d.html new file mode 100644 index 0000000000..4590026b2c --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-registration-request/session-i-d.html @@ -0,0 +1,16 @@ + + +NetworkMapService.RegistrationRequest.sessionID - + + + +com.r3corda.node.services.network / NetworkMapService / RegistrationRequest / sessionID
      +
      +

      sessionID

      + +val sessionID: Long
      +Overrides ServiceRequestMessage.sessionID
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/index.html index 285562de31..7a60bdd25e 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.network / NetworkMapService / SubscribeRequest

      SubscribeRequest

      -class SubscribeRequest : AbstractRequestMessage
      +class SubscribeRequest : NetworkMapRequestMessage


      Constructors

      @@ -26,6 +26,12 @@ +sessionID + +val sessionID: Long + + + subscribe val subscribe: Boolean @@ -37,15 +43,20 @@ -replyTo +replyTo val replyTo: MessageRecipients + + +

      Inherited Functions

      + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
      -sessionID -val sessionID: Long?
      diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/session-i-d.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/session-i-d.html new file mode 100644 index 0000000000..b92dabcc49 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/-subscribe-request/session-i-d.html @@ -0,0 +1,16 @@ + + +NetworkMapService.SubscribeRequest.sessionID - + + + +com.r3corda.node.services.network / NetworkMapService / SubscribeRequest / sessionID
      +
      +

      sessionID

      + +val sessionID: Long
      +Overrides ServiceRequestMessage.sessionID
      +
      +
      + + diff --git a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/index.html b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/index.html index 35a0077a22..3b56656b12 100644 --- a/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.network/-network-map-service/index.html @@ -21,7 +21,7 @@ replace each other based on a serial number present in the change.

      FetchMapRequest -class FetchMapRequest : AbstractRequestMessage +class FetchMapRequest : NetworkMapRequestMessage @@ -31,9 +31,15 @@ replace each other based on a serial number present in the change.

      +NetworkMapRequestMessage + +abstract class NetworkMapRequestMessage : ServiceRequestMessage + + + QueryIdentityRequest -class QueryIdentityRequest : AbstractRequestMessage +class QueryIdentityRequest : NetworkMapRequestMessage @@ -45,7 +51,7 @@ replace each other based on a serial number present in the change.

      RegistrationRequest -class RegistrationRequest : AbstractRequestMessage +class RegistrationRequest : NetworkMapRequestMessage @@ -57,7 +63,7 @@ replace each other based on a serial number present in the change.

      SubscribeRequest -class SubscribeRequest : AbstractRequestMessage +class SubscribeRequest : NetworkMapRequestMessage diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/-init-.html index 14768621ce..dbc2cfb1ba 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.persistence / DataVendingService / <init>

      <init>

      -DataVendingService(net: MessagingService, storage: StorageService)
      +DataVendingService(net: MessagingService, storage: StorageService, networkMapCache: NetworkMapCache)

      This class sets up network message handlers for requests from peers for data keyed by hash. It is a piece of simple glue that sits between the network layer and the database layer.

      Note that in our data model, to be able to name a thing by hash automatically gives the power to request it. There diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/index.html b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/index.html index c2a6754647..c7a041f938 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending-service/index.html @@ -27,7 +27,7 @@ such the hash of a piece of data can be seen as a type of password allowing acce <init> -DataVendingService(net: MessagingService, storage: StorageService)

      This class sets up network message handlers for requests from peers for data keyed by hash. It is a piece of simple +DataVendingService(net: MessagingService, storage: StorageService, networkMapCache: NetworkMapCache)

      This class sets up network message handlers for requests from peers for data keyed by hash. It is a piece of simple glue that sits between the network layer and the database layer.

      @@ -42,6 +42,12 @@ glue that sits between the network layer and the database layer.

      val net: MessagingService + + +networkMapCache + +val networkMapCache: NetworkMapCache +

      Inherited Functions

      @@ -51,10 +57,12 @@ glue that sits between the network layer and the database layer.

      addMessageHandler -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

      -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

      +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

      +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

      Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/index.html b/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/index.html index 238789d363..cd7b09ca62 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/index.html @@ -95,10 +95,8 @@ operation due to the need to copy the bytes to disk and hash them along the way. openAttachment -fun openAttachment(id: SecureHash): Attachment?

      Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

      +fun openAttachment(id: SecureHash): Attachment?

      Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.

      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/open-attachment.html b/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/open-attachment.html index 9e304ff5b7..dd8f8d3880 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/open-attachment.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-node-attachment-service/open-attachment.html @@ -10,10 +10,8 @@ fun openAttachment(id: SecureHash): Attachment?
      Overrides AttachmentStorage.openAttachment
      -

      Returns a newly opened stream for the given locally stored attachment, or null if no such attachment is known. -The returned stream must be closed when you are done with it to avoid resource leaks. You should probably wrap -the result in a JarInputStream unless youre sending it somewhere, there is a convenience helper for this -on Attachment.

      +

      Returns a handle to a locally stored attachment, or null if its not known. The handle can be used to open +a stream for the data, which will be a zip/jar file.



      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-per-file-checkpoint-storage/checkpoints.html b/docs/build/html/api/com.r3corda.node.services.persistence/-per-file-checkpoint-storage/checkpoints.html index 01cf8c7e90..420b79c8c3 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-per-file-checkpoint-storage/checkpoints.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-per-file-checkpoint-storage/checkpoints.html @@ -13,11 +13,11 @@ Overrides fun getTransaction(id: SecureHash): SignedTransaction?
      -Overrides TransactionStorage.getTransaction
      +Overrides ReadOnlyTransactionStorage.getTransaction

      Return the transaction with the given id, or null if no such transaction exists.



      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/index.html b/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/index.html index 2e5dcd470b..dc9b90fa2f 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/index.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/index.html @@ -7,7 +7,7 @@ com.r3corda.node.services.persistence / StorageServiceImpl

      StorageServiceImpl

      -open class StorageServiceImpl : SingletonSerializeAsToken, StorageService
      +open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService


      Constructors

      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/validated-transactions.html b/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/validated-transactions.html index 1c6573f60b..be18831cc0 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/validated-transactions.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-storage-service-impl/validated-transactions.html @@ -9,7 +9,7 @@

      validatedTransactions

      open val validatedTransactions: TransactionStorage
      -Overrides StorageService.validatedTransactions
      +Overrides TxWritableStorageService.validatedTransactions

      A map of hash->tx where tx has been signature/contract validated and the states are known to be correct. The signatures arent technically needed after that point, but we keep them around so that we can relay the transaction data to other nodes that need it.

      diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/index.html b/docs/build/html/api/com.r3corda.node.services.persistence/index.html index 1416e0f9a0..4d42e3fbb3 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/index.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/index.html @@ -43,7 +43,7 @@ glue that sits between the network layer and the database layer.

      StorageServiceImpl -open class StorageServiceImpl : SingletonSerializeAsToken, StorageService +open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/index.html index c1273b9b9f..bcd3721b90 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/index.html @@ -65,12 +65,6 @@ For any given flow there is only one PSM, even if that protocol invokes subproto -prepareForResumeWith - -fun prepareForResumeWith(serviceHub: ServiceHubInternal, receivedPayload: Any?, suspendAction: (FiberRequest, ProtocolStateMachineImpl<*>) -> Unit): Unit - - - receive fun <T : Any> receive(topic: String, sessionIDForReceive: Long, recvType: Class<T>): UntrustworthyData<T> @@ -85,13 +79,13 @@ For any given flow there is only one PSM, even if that protocol invokes subproto send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any, recvType: Class<T>): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send-and-receive.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send-and-receive.html index d5acaa5f08..878461decf 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send-and-receive.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send-and-receive.html @@ -7,8 +7,8 @@ com.r3corda.node.services.statemachine / ProtocolStateMachineImpl / sendAndReceive

      sendAndReceive

      - -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any, recvType: Class<T>): UntrustworthyData<T>
      + +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T>
      Overrides ProtocolStateMachine.sendAndReceive


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send.html index 495a7e71b3..26fa59ee59 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/send.html @@ -7,8 +7,8 @@ com.r3corda.node.services.statemachine / ProtocolStateMachineImpl / send

      send

      - -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit
      + +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
      Overrides ProtocolStateMachine.send


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/-init-.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/-init-.html index d931c86eb6..c4bcd5a38b 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.statemachine / StateMachineManager / FiberRequest / ExpectingResponse / <init>

      <init>

      -ExpectingResponse(topic: String, destination: MessageRecipients?, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any?, responseType: Class<R>)
      +ExpectingResponse(topic: String, destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any?, responseType: Class<R>)


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/index.html index e7770d6429..8122b575b1 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-expecting-response/index.html @@ -17,7 +17,7 @@ <init> -ExpectingResponse(topic: String, destination: MessageRecipients?, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any?, responseType: Class<R>) +ExpectingResponse(topic: String, destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any?, responseType: Class<R>) @@ -39,7 +39,7 @@ destination -val destination: MessageRecipients? +val destination: Party? diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-init-.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-init-.html index 104b4b69b3..cb46428641 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.statemachine / StateMachineManager / FiberRequest / <init>

      <init>

      -FiberRequest(topic: String, destination: MessageRecipients?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?)
      +FiberRequest(topic: String, destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?)


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/-init-.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/-init-.html index 6d7491289f..237cecc18f 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.statemachine / StateMachineManager / FiberRequest / NotExpectingResponse / <init>

      <init>

      -NotExpectingResponse(topic: String, destination: MessageRecipients, sessionIDForSend: Long, obj: Any?)
      +NotExpectingResponse(topic: String, destination: Party, sessionIDForSend: Long, obj: Any?)


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/index.html index 28a3d08a64..6d788ec6bd 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/-not-expecting-response/index.html @@ -17,7 +17,7 @@ <init> -NotExpectingResponse(topic: String, destination: MessageRecipients, sessionIDForSend: Long, obj: Any?) +NotExpectingResponse(topic: String, destination: Party, sessionIDForSend: Long, obj: Any?) @@ -28,7 +28,7 @@ destination -val destination: MessageRecipients? +val destination: Party? diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/destination.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/destination.html index abc288fede..47dab798ca 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/destination.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/destination.html @@ -8,7 +8,7 @@

      destination

      -val destination: MessageRecipients?
      +val destination: Party?


      diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/index.html index b5cc0292f1..96a93abf5d 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-fiber-request/index.html @@ -34,7 +34,7 @@ <init> -FiberRequest(topic: String, destination: MessageRecipients?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?) +FiberRequest(topic: String, destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?) @@ -45,7 +45,7 @@ destination -val destination: MessageRecipients? +val destination: Party? diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/commit.html b/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/commit.html index c707434a89..df563e84f1 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/commit.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/commit.html @@ -7,8 +7,8 @@ com.r3corda.node.services.transactions / InMemoryUniquenessProvider / commit

      commit

      - -fun commit(tx: WireTransaction, callerIdentity: Party): Unit
      + +fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit
      Overrides UniquenessProvider.commit

      Commits all input states of the given transaction


      diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/index.html b/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/index.html index bfb7ef8a94..4760896848 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/index.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-in-memory-uniqueness-provider/index.html @@ -30,7 +30,7 @@ commit -fun commit(tx: WireTransaction, callerIdentity: Party): Unit

      Commits all input states of the given transaction

      +fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit

      Commits all input states of the given transaction

      diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/-init-.html index d76d9bfec3..76b4d21805 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.transactions / NotaryService / <init>

      <init>

      -NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
      +NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

      A Notary service acts as the final signer of a transaction ensuring two things:

      • The (optional) timestamp of the transaction is valid

      • None of the referenced input states have previously been consumed by a transaction signed by this Notary

        diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/index.html b/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/index.html index 4fa904c814..c503fac403 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-notary-service/index.html @@ -35,7 +35,7 @@ <init> -NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A Notary service acts as the final signer of a transaction ensuring two things:

        +NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

        A Notary service acts as the final signer of a transaction ensuring two things:

        @@ -85,6 +85,12 @@ val net: MessagingService + + +networkMapCache + +val networkMapCache: NetworkMapCache +

        Inherited Functions

        @@ -94,10 +100,12 @@ addMessageHandler -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are caught and passed to the provided consumer.

        -fun <Q : AbstractRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of -common boilerplate code. Exceptions are propagated to the messaging layer.

        +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

        +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

        diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/-init-.html index 8b85c702a6..8442cab8f1 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.transactions / SimpleNotaryService / <init>

        <init>

        -SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
        +SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

        A simple Notary service that does not perform transaction validation



        diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/index.html b/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/index.html index 9fe6c8c00d..e17b6a7620 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-simple-notary-service/index.html @@ -29,7 +29,7 @@ <init> -SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A simple Notary service that does not perform transaction validation

        +SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

        A simple Notary service that does not perform transaction validation

        diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/-init-.html index 4721976041..e100b881f7 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.transactions / ValidatingNotaryService / <init>

        <init>

        -ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
        +ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

        A Notary service that validates the transaction chain of he submitted transaction before committing it



        diff --git a/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/index.html b/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/index.html index c5d5b27f0c..dff848d12d 100644 --- a/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.transactions/-validating-notary-service/index.html @@ -29,7 +29,7 @@ <init> -ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A Notary service that validates the transaction chain of he submitted transaction before committing it

        +ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)

        A Notary service that validates the transaction chain of he submitted transaction before committing it

        diff --git a/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/-init-.html b/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/-init-.html index 57e3cdbb98..7341e27fb8 100644 --- a/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/-init-.html @@ -7,10 +7,9 @@ com.r3corda.node.services.wallet / NodeWalletService / <init>

        <init>

        -NodeWalletService(services: ServiceHubInternal)
        -

        This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

        +NodeWalletService(services: ServiceHub)
        +

        Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).



        diff --git a/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/index.html b/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/index.html index 3529cbe2c0..13e89e1df5 100644 --- a/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.wallet/-node-wallet-service/index.html @@ -7,10 +7,9 @@ com.r3corda.node.services.wallet / NodeWalletService

        NodeWalletService

        -class NodeWalletService : SingletonSerializeAsToken, WalletService
        -

        This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

        +class NodeWalletService : InMemoryWalletService
        +

        Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).



        Constructors

        @@ -20,91 +19,51 @@ states relevant to us into a database and once such a wallet is implemented, thi <init> -NodeWalletService(services: ServiceHubInternal)

        This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

        +NodeWalletService(services: ServiceHub)

        Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).

        -

        Properties

        +

        Inherited Properties

        +currentWallet - - - - +linearHeads +updates
        -cashBalances -val cashBalances: Map<Currency, Amount<Currency>>

        Returns a snapshot of how much cash we have in each currency, ignoring details like issuer. Note: currencies for -which we have no cash evaluate to null, not 0.

        -
        -currentWallet -val currentWallet: Wallet

        Returns a read-only snapshot of the wallet at the time the call is made. Note that if you consume states or +open val currentWallet: 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.

        -linearHeads -val linearHeads: Map<SecureHash, StateAndRef<LinearState>>

        Returns a snapshot of the heads of LinearStates

        +open val linearHeads: Map<SecureHash, StateAndRef<LinearState>>

        Returns a snapshot of the heads of LinearStates

        -updates -val updates: <ERROR CLASS><Update>

        Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate +open val updates: <ERROR CLASS><Update>

        Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate the update.

        -

        Functions

        - - - - - - - -
        -notifyAll -fun notifyAll(txns: Iterable<WireTransaction>): Wallet

        Possibly update the wallet by marking as spent states that these transactions consume, and adding any relevant -new states that they create. You should only insert transactions that have been successfully verified here

        -

        Inherited Functions

        +notifyAll - - - - - - - - - - - -
        -linearHeadsOfType_ -open fun <T : LinearState> linearHeadsOfType_(stateType: Class<T>): Map<SecureHash, StateAndRef<T>>

        Returns the linearHeads only when the type of the state would be considered an instanceof the given type.

        +open fun notifyAll(txns: Iterable<WireTransaction>): Wallet

        Possibly update the wallet by marking as spent states that these transactions consume, and adding any relevant +new states that they create. You should only insert transactions that have been successfully verified here

        -notify -open fun notify(tx: WireTransaction): Wallet

        Same as notifyAll but with a single transaction.

        -
        -statesForRefs -open fun statesForRefs(refs: List<StateRef>): Map<StateRef, ContractState?>
        -toToken -open fun toToken(context: SerializeAsTokenContext): SerializationToken

        Extension Functions

        diff --git a/docs/build/html/api/com.r3corda.node.services.wallet/index.html b/docs/build/html/api/com.r3corda.node.services.wallet/index.html index ffa951cd2d..dddfdb0d55 100644 --- a/docs/build/html/api/com.r3corda.node.services.wallet/index.html +++ b/docs/build/html/api/com.r3corda.node.services.wallet/index.html @@ -21,19 +21,8 @@ NodeWalletService -class NodeWalletService : SingletonSerializeAsToken, WalletService

        This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience -method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist -states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.

        - - - - -WalletImpl - -class WalletImpl : Wallet

        A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance, -because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to -change out from underneath you, even though the canonical currently-best-known wallet may change as we learn -about new transactions from our peers and generate new transactions that consume states ourselves.

        +class NodeWalletService : InMemoryWalletService

        Currently, the node wallet service is just the in-memory wallet service until we have finished evaluating and +selecting a persistence layer (probably an ORM over a SQL DB).

        diff --git a/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/index.html b/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/index.html new file mode 100644 index 0000000000..5a558837e1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/index.html @@ -0,0 +1,30 @@ + + +FixingSessionInitiationHandler - + + + +com.r3corda.node.services / FixingSessionInitiationHandler
        +
        +

        FixingSessionInitiationHandler

        +object FixingSessionInitiationHandler
        +

        This is a temporary handler required for establishing random sessionIDs for the Fixer and Floater as part of +running scheduled fixings for the InterestRateSwap contract.

        +

        TODO: This will be replaced with the automatic sessionID / session setup work.

        +
        +
        +
        +
        +

        Functions

        + + + + + + + +
        +register +fun register(node: AbstractNode): Unit
        + + diff --git a/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/register.html b/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/register.html new file mode 100644 index 0000000000..380cbf494b --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/-fixing-session-initiation-handler/register.html @@ -0,0 +1,15 @@ + + +FixingSessionInitiationHandler.register - + + + +com.r3corda.node.services / FixingSessionInitiationHandler / register
        +
        +

        register

        + +fun register(node: AbstractNode): Unit
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.services/-notary-change-service/-init-.html b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/-init-.html new file mode 100644 index 0000000000..9f2352bca7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/-init-.html @@ -0,0 +1,16 @@ + + +NotaryChangeService.<init> - + + + +com.r3corda.node.services / NotaryChangeService / <init>
        +
        +

        <init>

        +NotaryChangeService(net: MessagingService, smm: StateMachineManager, networkMapCache: NetworkMapCache)
        +

        A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.services/-notary-change-service/index.html b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/index.html new file mode 100644 index 0000000000..ad53553c00 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/index.html @@ -0,0 +1,74 @@ + + +NotaryChangeService - + + + +com.r3corda.node.services / NotaryChangeService
        +
        +

        NotaryChangeService

        +class NotaryChangeService : AbstractNodeService
        +

        A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

        +
        +
        +

        Constructors

        + + + + + + + +
        +<init> +NotaryChangeService(net: MessagingService, smm: StateMachineManager, networkMapCache: NetworkMapCache)

        A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

        +
        +

        Properties

        + + + + + + + +
        +smm +val smm: StateMachineManager
        +

        Inherited Properties

        + + + + + + + + + + + +
        +net +val net: MessagingService
        +networkMapCache +val networkMapCache: NetworkMapCache
        +

        Inherited Functions

        + + + + + + + +
        +addMessageHandler +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R, exceptionConsumer: (Message, Exception) -> Unit): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are caught and passed to the provided consumer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

        +fun <Q : ServiceRequestMessage, R : Any> addMessageHandler(topic: String, handler: (Q) -> R): Unit

        Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of +common boilerplate code. Exceptions are propagated to the messaging layer. If you just want a simple +acknowledgement response with no content, use com.r3corda.core.messaging.Ack

        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.services/-notary-change-service/smm.html b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/smm.html new file mode 100644 index 0000000000..f3d3d68626 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/-notary-change-service/smm.html @@ -0,0 +1,15 @@ + + +NotaryChangeService.smm - + + + +com.r3corda.node.services / NotaryChangeService / smm
        +
        +

        smm

        + +val smm: StateMachineManager
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.services/index.html b/docs/build/html/api/com.r3corda.node.services/index.html new file mode 100644 index 0000000000..4557db0650 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services/index.html @@ -0,0 +1,32 @@ + + +com.r3corda.node.services - + + + +com.r3corda.node.services
        +
        +

        Package com.r3corda.node.services

        +

        Types

        + + + + + + + + + + + +
        +FixingSessionInitiationHandler +object FixingSessionInitiationHandler

        This is a temporary handler required for establishing random sessionIDs for the Fixer and Floater as part of +running scheduled fixings for the InterestRateSwap contract.

        +
        +NotaryChangeService +class NotaryChangeService : AbstractNodeService

        A service that monitors the network for requests for changing the notary of a state, +and immediately runs the NotaryChangeProtocol if the auto-accept criteria are met.

        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-gate/is-on-thread.html b/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-gate/is-on-thread.html index 5954600465..e35ef8f93b 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-gate/is-on-thread.html +++ b/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-gate/is-on-thread.html @@ -11,9 +11,9 @@ val isOnThread: Boolean
        Overrides AffinityExecutor.isOnThread

        Returns true if the current thread is equal to the thread this executor is backed by.

        -Getter
        +

        Getter

        Returns true if the current thread is equal to the thread this executor is backed by.

        -
        +



        diff --git a/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-service-affinity-executor/is-on-thread.html b/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-service-affinity-executor/is-on-thread.html index d683a81611..c602ed4dd3 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-service-affinity-executor/is-on-thread.html +++ b/docs/build/html/api/com.r3corda.node.utilities/-affinity-executor/-service-affinity-executor/is-on-thread.html @@ -11,9 +11,9 @@ val isOnThread: Boolean
        Overrides AffinityExecutor.isOnThread

        Returns true if the current thread is equal to the thread this executor is backed by.

        -Getter
        +

        Getter

        Returns true if the current thread is equal to the thread this executor is backed by.

        -
        +



        diff --git a/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/deserialize.html b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/deserialize.html new file mode 100644 index 0000000000..cae90d4fc1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/deserialize.html @@ -0,0 +1,15 @@ + + +JsonSupport.PublicKeyDeserializer.deserialize - + + + +com.r3corda.node.utilities / JsonSupport / PublicKeyDeserializer / deserialize
        +
        +

        deserialize

        + +fun deserialize(parser: <ERROR CLASS>, context: <ERROR CLASS>): <ERROR CLASS>
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/index.html b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/index.html new file mode 100644 index 0000000000..044f09384e --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-deserializer/index.html @@ -0,0 +1,25 @@ + + +JsonSupport.PublicKeyDeserializer - + + + +com.r3corda.node.utilities / JsonSupport / PublicKeyDeserializer
        +
        +

        PublicKeyDeserializer

        +object PublicKeyDeserializer
        +
        +
        +

        Functions

        + + + + + + + +
        +deserialize +fun deserialize(parser: <ERROR CLASS>, context: <ERROR CLASS>): <ERROR CLASS>
        + + diff --git a/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/index.html b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/index.html new file mode 100644 index 0000000000..1c1bacdf8a --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/index.html @@ -0,0 +1,25 @@ + + +JsonSupport.PublicKeySerializer - + + + +com.r3corda.node.utilities / JsonSupport / PublicKeySerializer
        +
        +

        PublicKeySerializer

        +object PublicKeySerializer
        +
        +
        +

        Functions

        + + + + + + + +
        +serialize +fun serialize(obj: <ERROR CLASS>, generator: <ERROR CLASS>, provider: <ERROR CLASS>): Unit
        + + diff --git a/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/serialize.html b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/serialize.html new file mode 100644 index 0000000000..cc7b23b9b2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.utilities/-json-support/-public-key-serializer/serialize.html @@ -0,0 +1,15 @@ + + +JsonSupport.PublicKeySerializer.serialize - + + + +com.r3corda.node.utilities / JsonSupport / PublicKeySerializer / serialize
        +
        +

        serialize

        + +fun serialize(obj: <ERROR CLASS>, generator: <ERROR CLASS>, provider: <ERROR CLASS>): Unit
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.node.utilities/-json-support/index.html b/docs/build/html/api/com.r3corda.node.utilities/-json-support/index.html index ea930ba873..43902e383d 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/-json-support/index.html +++ b/docs/build/html/api/com.r3corda.node.utilities/-json-support/index.html @@ -47,6 +47,18 @@ the java.time API, some core types, and Kotlin data classes.

        +PublicKeyDeserializer + +object PublicKeyDeserializer + + + +PublicKeySerializer + +object PublicKeySerializer + + + SecureHashDeserializer class SecureHashDeserializer<T : SecureHash>

        Implemented as a class so that we can instantiate for T

        diff --git a/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/index.html b/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/index.html index 02997984e6..fac91e9a32 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/index.html +++ b/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/index.html @@ -86,7 +86,7 @@ used in demos or testing. This will also substitute a Fiber compatible Future i TestClock -class TestClock : MutableClock

        A Clock that can have the time advanced for use in testing

        +class TestClock : MutableClock, SerializeAsToken

        A Clock that can have the time advanced for use in testing

        diff --git a/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/mutations.html b/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/mutations.html index 4208233028..075657a01e 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/mutations.html +++ b/docs/build/html/api/com.r3corda.node.utilities/-mutable-clock/mutations.html @@ -10,9 +10,9 @@ val mutations: <ERROR CLASS><Long>

        This is an observer on the mutation count of this Clock, which reflects the occurence of mutations.

        -Getter
        +

        Getter

        This is an observer on the mutation count of this Clock, which reflects the occurence of mutations.

        -
        +



        diff --git a/docs/build/html/api/com.r3corda.node.utilities/java.time.-clock/await-with-deadline.html b/docs/build/html/api/com.r3corda.node.utilities/java.time.-clock/await-with-deadline.html index 3d9f5f024f..858081b983 100644 --- a/docs/build/html/api/com.r3corda.node.utilities/java.time.-clock/await-with-deadline.html +++ b/docs/build/html/api/com.r3corda.node.utilities/java.time.-clock/await-with-deadline.html @@ -11,8 +11,8 @@ fun Clock.awaitWithDeadline(deadline: Instant, future: Future<*> = SettableFuture<Any>()): Boolean

        Wait until the given Future is complete or the deadline is reached, with support for MutableClock implementations used in demos or testing. This will also substitute a Fiber compatible Future if required

        -Return
        -true if the Future is complete, false if the deadline was reached
        +

        Return
        +true if the Future is complete, false if the deadline was reached



        diff --git a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/-init-.html b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/-init-.html index 54940ca7fe..5b993c87ee 100644 --- a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/-init-.html @@ -7,9 +7,7 @@ com.r3corda.protocols / AbstractRequestMessage / <init>

        <init>

        -AbstractRequestMessage(replyTo: MessageRecipients, sessionID: Long?)
        -

        Abstract superclass for request messages sent to services, which includes common -fields such as replyTo and replyToTopic.

        +AbstractRequestMessage(replyToParty: Party)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/get-reply-to.html b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/get-reply-to.html new file mode 100644 index 0000000000..23a77f2d11 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/get-reply-to.html @@ -0,0 +1,16 @@ + + +AbstractRequestMessage.getReplyTo - + + + +com.r3corda.protocols / AbstractRequestMessage / getReplyTo
        +
        +

        getReplyTo

        + +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        +Overrides ServiceRequestMessage.getReplyTo
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/index.html b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/index.html index 6e980b35eb..c3ffea5405 100644 --- a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/index.html @@ -7,9 +7,7 @@ com.r3corda.protocols / AbstractRequestMessage

        AbstractRequestMessage

        -abstract class AbstractRequestMessage
        -

        Abstract superclass for request messages sent to services, which includes common -fields such as replyTo and replyToTopic.

        +abstract class AbstractRequestMessage : ServiceRequestMessage


        Constructors

        @@ -19,9 +17,7 @@ fields such as replyTo and replyToTopic.

        <init> -AbstractRequestMessage(replyTo: MessageRecipients, sessionID: Long?)

        Abstract superclass for request messages sent to services, which includes common -fields such as replyTo and replyToTopic.

        - +AbstractRequestMessage(replyToParty: Party) @@ -30,15 +26,31 @@ fields such as replyTo and replyToTopic.

        -replyTo +replyToParty -val replyTo: MessageRecipients +val replyToParty: Party + + +

        Inherited Properties

        + + +sessionID +abstract val sessionID: Long + + +
        -sessionID -val sessionID: Long?
        +

        Functions

        + + + + +
        +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        @@ -47,21 +59,15 @@ fields such as replyTo and replyToTopic.

        -FetchMapRequest - -class FetchMapRequest : AbstractRequestMessage - - - Handshake class Handshake : AbstractRequestMessage -QueryIdentityRequest +Handshake -class QueryIdentityRequest : AbstractRequestMessage +class Handshake : AbstractRequestMessage @@ -71,12 +77,6 @@ fields such as replyTo and replyToTopic.

        -RegistrationRequest - -class RegistrationRequest : AbstractRequestMessage - - - Request class Request : AbstractRequestMessage @@ -87,12 +87,6 @@ fields such as replyTo and replyToTopic.

        class SignRequest : AbstractRequestMessage - - -SubscribeRequest - -class SubscribeRequest : AbstractRequestMessage - diff --git a/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/reply-to-party.html b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/reply-to-party.html new file mode 100644 index 0000000000..3d2dea4bb6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-abstract-request-message/reply-to-party.html @@ -0,0 +1,15 @@ + + +AbstractRequestMessage.replyToParty - + + + +com.r3corda.protocols / AbstractRequestMessage / replyToParty
        +
        +

        replyToParty

        + +val replyToParty: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/-init-.html index 33637d3751..ba523ca4e7 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / FetchAttachmentsProtocol / <init>

        <init>

        -FetchAttachmentsProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)
        +FetchAttachmentsProtocol(requests: Set<SecureHash>, otherSide: Party)

        Given a set of hashes either loads from from local storage or requests them from the other peer. Downloaded attachments are saved to local storage automatically.


        diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/index.html index 2bda50078b..7b07d87cce 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-attachments-protocol/index.html @@ -19,7 +19,7 @@ attachments are saved to local storage automatically.

        <init> -FetchAttachmentsProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)

        Given a set of hashes either loads from from local storage or requests them from the other peer. Downloaded +FetchAttachmentsProtocol(requests: Set<SecureHash>, otherSide: Party)

        Given a set of hashes either loads from from local storage or requests them from the other peer. Downloaded attachments are saved to local storage automatically.

        @@ -43,7 +43,7 @@ attachments are saved to local storage automatically.

        otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-init-.html index 70e5ccf6f5..d9f3452373 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / FetchDataProtocol / <init>

        <init>

        -FetchDataProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)
        +FetchDataProtocol(requests: Set<SecureHash>, otherSide: Party)

        An abstract protocol for fetching typed data from a remote peer.

        Given a set of hashes (IDs), either loads them from local disk or asks the remote peer to provide them.

        A malicious response in which the data provided by the remote peer does not hash to the requested hash results in diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/-init-.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/-init-.html index c1b1ac5b47..1e9b3752a1 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / FetchDataProtocol / Request / <init>

        <init>

        -Request(hashes: List<SecureHash>, replyTo: SingleMessageRecipient, sessionID: Long)
        +Request(hashes: List<SecureHash>, replyTo: Party, sessionID: Long)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/index.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/index.html index c8a35a3b22..a6e7ae7b98 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/index.html @@ -17,7 +17,7 @@ <init> -Request(hashes: List<SecureHash>, replyTo: SingleMessageRecipient, sessionID: Long) +Request(hashes: List<SecureHash>, replyTo: Party, sessionID: Long) @@ -30,6 +30,12 @@ val hashes: List<SecureHash> + + +sessionID + +val sessionID: Long +

        Inherited Properties

        @@ -37,15 +43,20 @@ -replyTo +replyToParty -val replyTo: MessageRecipients +val replyToParty: Party + + +

        Inherited Functions

        + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        -sessionID -val sessionID: Long?
        diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/session-i-d.html new file mode 100644 index 0000000000..75489170f8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/-request/session-i-d.html @@ -0,0 +1,16 @@ + + +FetchDataProtocol.Request.sessionID - + + + +com.r3corda.protocols / FetchDataProtocol / Request / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +Overrides ServiceRequestMessage.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/index.html index 920f48dab7..9b00d39da2 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/index.html @@ -73,7 +73,7 @@ same as the ultimate type, you must also override convert <init> -FetchDataProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)

        An abstract protocol for fetching typed data from a remote peer.

        +FetchDataProtocol(requests: Set<SecureHash>, otherSide: Party)

        An abstract protocol for fetching typed data from a remote peer.

        @@ -85,7 +85,7 @@ same as the ultimate type, you must also override convert otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party @@ -132,7 +132,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -181,13 +183,13 @@ progress.

        send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/other-side.html b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/other-side.html index 2b1c29c0db..6b3c698ba1 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-data-protocol/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -protected val otherSide: SingleMessageRecipient
        +protected val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/-init-.html index ee12b9d457..f96720e4f4 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / FetchTransactionsProtocol / <init>

        <init>

        -FetchTransactionsProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)
        +FetchTransactionsProtocol(requests: Set<SecureHash>, otherSide: Party)

        Given a set of tx hashes (IDs), either loads them from local disk or asks the remote peer to provide them.

        A malicious response in which the data provided by the remote peer does not hash to the requested hash results in FetchDataProtocol.DownloadedVsRequestedDataMismatch being thrown. If the remote peer doesnt have an entry, it diff --git a/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/index.html index 5da6ca0b8b..e7f0fe9061 100644 --- a/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-fetch-transactions-protocol/index.html @@ -24,7 +24,7 @@ the database, because its up to the caller to actually verify the transactions a <init> -FetchTransactionsProtocol(requests: Set<SecureHash>, otherSide: SingleMessageRecipient)

        Given a set of tx hashes (IDs), either loads them from local disk or asks the remote peer to provide them.

        +FetchTransactionsProtocol(requests: Set<SecureHash>, otherSide: Party)

        Given a set of tx hashes (IDs), either loads them from local disk or asks the remote peer to provide them.

        @@ -47,7 +47,7 @@ the database, because its up to the caller to actually verify the transactions a otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/-init-.html b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/-init-.html new file mode 100644 index 0000000000..0e2ac5c831 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/-init-.html @@ -0,0 +1,14 @@ + + +NotaryError.SignaturesMissing.<init> - + + + +com.r3corda.protocols / NotaryError / SignaturesMissing / <init>
        +
        +

        <init>

        +SignaturesMissing(missingSigners: List<PublicKey>)
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/index.html new file mode 100644 index 0000000000..fccdcec069 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/index.html @@ -0,0 +1,36 @@ + + +NotaryError.SignaturesMissing - + + + +com.r3corda.protocols / NotaryError / SignaturesMissing
        +
        +

        SignaturesMissing

        +class SignaturesMissing : NotaryError
        +
        +
        +

        Constructors

        + + + + + + + +
        +<init> +SignaturesMissing(missingSigners: List<PublicKey>)
        +

        Properties

        + + + + + + + +
        +missingSigners +val missingSigners: List<PublicKey>
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/missing-signers.html b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/missing-signers.html new file mode 100644 index 0000000000..30d8736421 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-error/-signatures-missing/missing-signers.html @@ -0,0 +1,15 @@ + + +NotaryError.SignaturesMissing.missingSigners - + + + +com.r3corda.protocols / NotaryError / SignaturesMissing / missingSigners
        +
        +

        missingSigners

        + +val missingSigners: List<PublicKey>
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-error/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-error/index.html index 75451724b6..cb59a7e405 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-error/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-error/index.html @@ -34,6 +34,12 @@ +SignaturesMissing + +class SignaturesMissing : NotaryError + + + TimestampInvalid class TimestampInvalid : NotaryError

        Thrown if the time specified in the timestamp command is outside the allowed tolerance

        @@ -71,6 +77,12 @@ +SignaturesMissing + +class SignaturesMissing : NotaryError + + + TimestampInvalid class TimestampInvalid : NotaryError

        Thrown if the time specified in the timestamp command is outside the allowed tolerance

        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/-init-.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/-init-.html index 81a131dc15..de6eddabdd 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / NotaryProtocol / Client / <init>

        <init>

        -Client(wtx: WireTransaction, progressTracker: ProgressTracker = Client.tracker())
        +Client(stx: SignedTransaction, progressTracker: ProgressTracker = Client.tracker())

        A protocol to be used for obtaining a signature from a NotaryService ascertaining the transaction timestamp is correct and none of its inputs have been used in another completed transaction

        Exceptions

        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/index.html index 6475462376..acf511d2d5 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/index.html @@ -40,7 +40,7 @@ by another transaction or the timestamp is invalid
        <init> -Client(wtx: WireTransaction, progressTracker: ProgressTracker = Client.tracker())

        A protocol to be used for obtaining a signature from a NotaryService ascertaining the transaction +Client(stx: SignedTransaction, progressTracker: ProgressTracker = Client.tracker())

        A protocol to be used for obtaining a signature from a NotaryService ascertaining the transaction timestamp is correct and none of its inputs have been used in another completed transaction

        @@ -51,9 +51,9 @@ timestamp is correct and none of its inputs have been used in another completed -notaryNode +notaryParty -lateinit var notaryNode: NodeInfo +lateinit var notaryParty: Party @@ -88,7 +88,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -112,20 +114,20 @@ progress.

        receive -fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        -fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/notary-party.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/notary-party.html new file mode 100644 index 0000000000..cb6af79ab5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-client/notary-party.html @@ -0,0 +1,15 @@ + + +NotaryProtocol.Client.notaryParty - + + + +com.r3corda.protocols / NotaryProtocol / Client / notaryParty
        +
        +

        notaryParty

        + +lateinit var notaryParty: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/create.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/create.html index 6a736e9e8e..9b88e30bdd 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/create.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/create.html @@ -7,8 +7,8 @@ com.r3corda.protocols / NotaryProtocol / DefaultFactory / create

        create

        - -fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
        + +fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
        Overrides Factory.create


        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/index.html index d0302b4e8a..b3c9ee74e0 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-default-factory/index.html @@ -17,7 +17,7 @@ create -fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service +fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/create.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/create.html index 03b5ef7da7..72aa0b33b7 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/create.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/create.html @@ -7,8 +7,8 @@ com.r3corda.protocols / NotaryProtocol / Factory / create

        create

        - -abstract fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
        + +abstract fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service


        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/index.html index 9a43703caf..8a1c1dcb9e 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-factory/index.html @@ -17,7 +17,7 @@ create -abstract fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service +abstract fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/-init-.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/-init-.html index 074d1dbee7..7e4dc37026 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / NotaryProtocol / Handshake / <init>

        <init>

        -Handshake(replyTo: SingleMessageRecipient, sendSessionID: Long, sessionID: Long)
        +Handshake(replyTo: Party, sendSessionID: Long, sessionID: Long)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/index.html index 1297361f9f..6ceb0b627b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/index.html @@ -17,7 +17,7 @@ <init> -Handshake(replyTo: SingleMessageRecipient, sendSessionID: Long, sessionID: Long) +Handshake(replyTo: Party, sendSessionID: Long, sessionID: Long) @@ -30,6 +30,12 @@ val sendSessionID: Long + + +sessionID + +val sessionID: Long +

        Inherited Properties

        @@ -37,15 +43,20 @@ -replyTo +replyToParty -val replyTo: MessageRecipients +val replyToParty: Party + + +

        Inherited Functions

        + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        -sessionID -val sessionID: Long?
        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/session-i-d.html new file mode 100644 index 0000000000..fca7e1c6e8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-handshake/session-i-d.html @@ -0,0 +1,16 @@ + + +NotaryProtocol.Handshake.sessionID - + + + +com.r3corda.protocols / NotaryProtocol / Handshake / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +Overrides ServiceRequestMessage.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/-init-.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/-init-.html index 01baddf5e8..abdae62367 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / NotaryProtocol / Service / <init>

        <init>

        -Service(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
        +Service(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        Checks that the timestamp command is valid (if present) and commits the input state, or returns a conflict if any of the input states have been previously committed.

        Extend this class, overriding beforeCommit to add custom transaction processing/validation logic.

        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/before-commit.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/before-commit.html index 12ea6799f1..077ca8b369 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/before-commit.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/before-commit.html @@ -7,8 +7,8 @@ com.r3corda.protocols / NotaryProtocol / Service / beforeCommit

        beforeCommit

        - -open fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
        + +open fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully resolving it into a TransactionForVerification, for which the caller would have to reveal the whole transaction history chain. diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/index.html index 24f1a6795b..7156a0fb1e 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/index.html @@ -23,7 +23,7 @@ if any of the input states have been previously committed.

        <init> -Service(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        Checks that the timestamp command is valid (if present) and commits the input state, or returns a conflict +Service(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        Checks that the timestamp command is valid (if present) and commits the input state, or returns a conflict if any of the input states have been previously committed.

        @@ -36,7 +36,7 @@ if any of the input states have been previously committed.

        otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party @@ -95,7 +95,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -107,7 +109,7 @@ progress.

        beforeCommit -open fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully +open fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully resolving it into a TransactionForVerification, for which the caller would have to reveal the whole transaction history chain. As a result, the Notary will commit invalid transactions as well, but as it also records the identity of @@ -138,13 +140,13 @@ undo the commit of the input states (the exact mechanism still needs to be worke send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/other-side.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/other-side.html index 6f53c2667d..1b1772344b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-service/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -val otherSide: SingleMessageRecipient
        +val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/-init-.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/-init-.html index d5f7cc9dbe..ee0b5e8fd9 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / NotaryProtocol / SignRequest / <init>

        <init>

        -SignRequest(txBits: SerializedBytes<WireTransaction>, callerIdentity: Party)
        +SignRequest(tx: SignedTransaction, callerIdentity: Party)

        TODO: The caller must authenticate instead of just specifying its identity



        diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/index.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/index.html index 51d792d627..7dd74ff415 100644 --- a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/index.html @@ -18,7 +18,7 @@ <init> -SignRequest(txBits: SerializedBytes<WireTransaction>, callerIdentity: Party)

        TODO: The caller must authenticate instead of just specifying its identity

        +SignRequest(tx: SignedTransaction, callerIdentity: Party)

        TODO: The caller must authenticate instead of just specifying its identity

        @@ -34,9 +34,9 @@ -txBits +tx -val txBits: SerializedBytes<WireTransaction> +val tx: SignedTransaction diff --git a/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/tx.html b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/tx.html new file mode 100644 index 0000000000..48bdf26c3f --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-notary-protocol/-sign-request/tx.html @@ -0,0 +1,15 @@ + + +NotaryProtocol.SignRequest.tx - + + + +com.r3corda.protocols / NotaryProtocol / SignRequest / tx
        +
        +

        tx

        + +val tx: SignedTransaction
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-init-.html index 4fbd27e9c9..23c6fb94d5 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / RatesFixProtocol / <init>

        <init>

        -RatesFixProtocol(tx: TransactionBuilder, oracle: NodeInfo, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))
        +RatesFixProtocol(tx: TransactionBuilder, oracle: Party, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, timeOut: Duration, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))

        This protocol queries the given oracle for an interest rate fix, and if it is within the given tolerance embeds the fix in the transaction and then proceeds to get the oracle to sign it. Although the call method combines the query and signing step, you can run the steps individually by constructing this object and then using the public methods diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/-init-.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/-init-.html index 59284c1eb3..072a4f3cf8 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / RatesFixProtocol / QueryRequest / <init>

        <init>

        -QueryRequest(queries: List<FixOf>, replyTo: SingleMessageRecipient, sessionID: Long)
        +QueryRequest(queries: List<FixOf>, replyTo: Party, sessionID: Long, deadline: Instant)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/deadline.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/deadline.html new file mode 100644 index 0000000000..3c91392aa4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/deadline.html @@ -0,0 +1,15 @@ + + +RatesFixProtocol.QueryRequest.deadline - + + + +com.r3corda.protocols / RatesFixProtocol / QueryRequest / deadline
        +
        +

        deadline

        + +val deadline: Instant
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/index.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/index.html index ff1e3afeed..4a55bc6c68 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/index.html @@ -17,7 +17,7 @@ <init> -QueryRequest(queries: List<FixOf>, replyTo: SingleMessageRecipient, sessionID: Long) +QueryRequest(queries: List<FixOf>, replyTo: Party, sessionID: Long, deadline: Instant) @@ -26,10 +26,22 @@ +deadline + +val deadline: Instant + + + queries val queries: List<FixOf> + + +sessionID + +val sessionID: Long +

        Inherited Properties

        @@ -37,15 +49,20 @@ -replyTo +replyToParty -val replyTo: MessageRecipients +val replyToParty: Party + + +

        Inherited Functions

        + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        -sessionID -val sessionID: Long?
        diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/session-i-d.html new file mode 100644 index 0000000000..bf45e9fe03 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-query-request/session-i-d.html @@ -0,0 +1,16 @@ + + +RatesFixProtocol.QueryRequest.sessionID - + + + +com.r3corda.protocols / RatesFixProtocol / QueryRequest / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +Overrides ServiceRequestMessage.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/-init-.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/-init-.html index b7a627088c..2ee1b5c0fc 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / RatesFixProtocol / SignRequest / <init>

        <init>

        -SignRequest(tx: WireTransaction, replyTo: SingleMessageRecipient, sessionID: Long)
        +SignRequest(tx: WireTransaction, replyTo: Party, sessionID: Long)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/index.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/index.html index 71451b5476..831f76e5b1 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/index.html @@ -17,7 +17,7 @@ <init> -SignRequest(tx: WireTransaction, replyTo: SingleMessageRecipient, sessionID: Long) +SignRequest(tx: WireTransaction, replyTo: Party, sessionID: Long) @@ -26,6 +26,12 @@ +sessionID + +val sessionID: Long + + + tx val tx: WireTransaction @@ -37,15 +43,20 @@ -replyTo +replyToParty -val replyTo: MessageRecipients +val replyToParty: Party + + +

        Inherited Functions

        + + +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        -sessionID -val sessionID: Long?
        diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/session-i-d.html new file mode 100644 index 0000000000..efe052d1ff --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/-sign-request/session-i-d.html @@ -0,0 +1,16 @@ + + +RatesFixProtocol.SignRequest.sessionID - + + + +com.r3corda.protocols / RatesFixProtocol / SignRequest / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +Overrides ServiceRequestMessage.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/index.html index cab8f669d2..072f7e9091 100644 --- a/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-rates-fix-protocol/index.html @@ -70,7 +70,7 @@ for each step.

        <init> -RatesFixProtocol(tx: TransactionBuilder, oracle: NodeInfo, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))

        This protocol queries the given oracle for an interest rate fix, and if it is within the given tolerance embeds the +RatesFixProtocol(tx: TransactionBuilder, oracle: Party, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, timeOut: Duration, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))

        This protocol queries the given oracle for an interest rate fix, and if it is within the given tolerance embeds the fix in the transaction and then proceeds to get the oracle to sign it. Although the call method combines the query and signing step, you can run the steps individually by constructing this object and then using the public methods for each step.

        @@ -120,7 +120,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -164,20 +166,20 @@ before its sent back to the oracle for signing (for example, adding output state receive -fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
        -fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/-init-.html index 2b6b24568e..ca646043e5 100644 --- a/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/-init-.html @@ -7,11 +7,11 @@ com.r3corda.protocols / ResolveTransactionsProtocol / <init>

        <init>

        -ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: SingleMessageRecipient)
        -ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: SingleMessageRecipient)
        +ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: Party)
        +ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: Party)


        -ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: SingleMessageRecipient)
        +ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: Party)

        This protocol fetches each transaction identified by the given hashes from either disk or network, along with all their dependencies, and verifies them together using a single TransactionGroup. If no exception is thrown, then all the transactions have been successfully verified and inserted into the local database.

        diff --git a/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/index.html index c7f10aa81c..e38471d22d 100644 --- a/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-resolve-transactions-protocol/index.html @@ -38,8 +38,8 @@ protocol is helpful when resolving and verifying a finished but partially signed <init> -ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: SingleMessageRecipient)
        -ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: SingleMessageRecipient)ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: SingleMessageRecipient)

        This protocol fetches each transaction identified by the given hashes from either disk or network, along with all +ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: Party)
        +ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: Party)ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: Party)

        This protocol fetches each transaction identified by the given hashes from either disk or network, along with all their dependencies, and verifies them together using a single TransactionGroup. If no exception is thrown, then all the transactions have been successfully verified and inserted into the local database.

        @@ -77,7 +77,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -101,20 +103,20 @@ progress.

        receive -fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
        -fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-service-request-message/get-reply-to.html b/docs/build/html/api/com.r3corda.protocols/-service-request-message/get-reply-to.html new file mode 100644 index 0000000000..ebfe8e1354 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-service-request-message/get-reply-to.html @@ -0,0 +1,15 @@ + + +ServiceRequestMessage.getReplyTo - + + + +com.r3corda.protocols / ServiceRequestMessage / getReplyTo
        +
        +

        getReplyTo

        + +abstract fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-service-request-message/index.html b/docs/build/html/api/com.r3corda.protocols/-service-request-message/index.html new file mode 100644 index 0000000000..74df70d2c3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-service-request-message/index.html @@ -0,0 +1,55 @@ + + +ServiceRequestMessage - + + + +com.r3corda.protocols / ServiceRequestMessage
        +
        +

        ServiceRequestMessage

        +interface ServiceRequestMessage
        +

        Abstract superclass for request messages sent to services, which includes common +fields such as replyTo and replyToTopic.

        +
        +
        +

        Properties

        + + + + + + + +
        +sessionID +abstract val sessionID: Long
        +

        Functions

        + + + + + + + +
        +getReplyTo +abstract fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
        +

        Inheritors

        + + + + + + + + + + + +
        +AbstractRequestMessage +abstract class AbstractRequestMessage : ServiceRequestMessage
        +NetworkMapRequestMessage +abstract class NetworkMapRequestMessage : ServiceRequestMessage
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-service-request-message/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-service-request-message/session-i-d.html new file mode 100644 index 0000000000..e16311b759 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-service-request-message/session-i-d.html @@ -0,0 +1,15 @@ + + +ServiceRequestMessage.sessionID - + + + +com.r3corda.protocols / ServiceRequestMessage / sessionID
        +
        +

        sessionID

        + +abstract val sessionID: Long
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/-init-.html index e6ce3d479a..1740ae331b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Acceptor / <init>

        <init>

        -Acceptor(otherSide: SingleMessageRecipient, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
        +Acceptor(otherSide: Party, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())

        One side of the protocol for inserting a pre-agreed deal.



        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/index.html index bfa0a41639..03f980cd59 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/index.html @@ -18,7 +18,7 @@ <init> -Acceptor(otherSide: SingleMessageRecipient, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())

        One side of the protocol for inserting a pre-agreed deal.

        +Acceptor(otherSide: Party, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())

        One side of the protocol for inserting a pre-agreed deal.

        @@ -34,6 +34,18 @@ +notary + +val notary: Party + + + +otherSide + +open val otherSide: Party + + + progressTracker open val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something @@ -42,28 +54,11 @@ tracker will be made a child of the current step in the parent. If its null, thi progress.

        - - -

        Inherited Properties

        - - +sessionID - - - - - - - - +open val sessionID: Long
        -notary -val notary: Party
        -otherSide -val otherSide: SingleMessageRecipient
        -sessionID -val sessionID: Long
        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/notary.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/notary.html new file mode 100644 index 0000000000..21a6b0190e --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/notary.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.Acceptor.notary - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Acceptor / notary
        +
        +

        notary

        + +val notary: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/other-side.html new file mode 100644 index 0000000000..612449703a --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/other-side.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Acceptor.otherSide - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Acceptor / otherSide
        +
        +

        otherSide

        + +open val otherSide: Party
        +Overrides Secondary.otherSide
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/session-i-d.html new file mode 100644 index 0000000000..a4b7f8e575 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-acceptor/session-i-d.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Acceptor.sessionID - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Acceptor / sessionID
        +
        +

        sessionID

        + +open val sessionID: Long
        +Overrides Secondary.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-f-i-x_-i-n-i-t-i-a-t-e_-t-o-p-i-c.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-f-i-x_-i-n-i-t-i-a-t-e_-t-o-p-i-c.html new file mode 100644 index 0000000000..90cb5fc58f --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-f-i-x_-i-n-i-t-i-a-t-e_-t-o-p-i-c.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.FIX_INITIATE_TOPIC - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FIX_INITIATE_TOPIC
        +
        +

        FIX_INITIATE_TOPIC

        + +val FIX_INITIATE_TOPIC: String
        +

        This topic exists purely for FixingSessionInitiation to be sent from FixingRoleDecider to FixingSessionInitiationHandler

        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/-init-.html index c937f9ec4b..1151015509 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/-init-.html @@ -7,10 +7,10 @@ com.r3corda.protocols / TwoPartyDealProtocol / Fixer / <init>

        <init>

        -Fixer(otherSide: SingleMessageRecipient, notary: Party, dealToFix: StateAndRef<T>, sessionID: Long, replacementProgressTracker: ProgressTracker? = null)
        +Fixer(initiation: FixingSessionInitiation, progressTracker: ProgressTracker = Secondary.tracker())

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        Do not infer too much from the name of the class. This is just to indicate that it is the "side" -of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for decided +of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for deciding who does what in the protocol.



        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/assemble-shared-t-x.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/assemble-shared-t-x.html index a67b63d287..d779b66114 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/assemble-shared-t-x.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/assemble-shared-t-x.html @@ -8,7 +8,7 @@

        assembleSharedTX

        -protected open fun assembleSharedTX(handshake: Handshake<StateRef>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>
        +protected fun assembleSharedTX(handshake: Handshake<StateRef>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/index.html index 2a2f597d1b..42fa221e1a 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/index.html @@ -7,10 +7,10 @@ com.r3corda.protocols / TwoPartyDealProtocol / Fixer

        Fixer

        -class Fixer<T : FixableDealState> : Secondary<StateRef>
        +class Fixer : Secondary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        Do not infer too much from the name of the class. This is just to indicate that it is the "side" -of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for decided +of the protocol that is run by the party with the fixed leg of swap deal, which is the basis for deciding who does what in the protocol.



        @@ -23,7 +23,7 @@ who does what in the protocol.

        <init> -Fixer(otherSide: SingleMessageRecipient, notary: Party, dealToFix: StateAndRef<T>, sessionID: Long, replacementProgressTracker: ProgressTracker? = null)

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        +Fixer(initiation: FixingSessionInitiation, progressTracker: ProgressTracker = Secondary.tracker())

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        @@ -33,15 +33,21 @@ who does what in the protocol.

        -dealToFix +initiation -val dealToFix: StateAndRef<T> +val initiation: FixingSessionInitiation + + + +otherSide + +val otherSide: Party progressTracker -open val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track progress.

        @@ -49,30 +55,7 @@ progress.

        -replacementProgressTracker - -val replacementProgressTracker: ProgressTracker? - - - -

        Inherited Properties

        - - - - - - - - - - - - +sessionID @@ -85,19 +68,13 @@ progress.

        - - - - +fun assembleSharedTX(handshake: Handshake<StateRef>): <ERROR CLASS><TransactionBuilder, List<PublicKey>> +fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef>
        -notary -val notary: Party
        -otherSide -val otherSide: SingleMessageRecipient
        -sessionID val sessionID: Long
        assembleSharedTX -open fun assembleSharedTX(handshake: Handshake<StateRef>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>
        -createTracker -fun createTracker(): ProgressTracker
        validateHandshake -open fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef>
        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/initiation.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/initiation.html new file mode 100644 index 0000000000..9fc8fc0dc4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/initiation.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.Fixer.initiation - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Fixer / initiation
        +
        +

        initiation

        + +val initiation: FixingSessionInitiation
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/other-side.html new file mode 100644 index 0000000000..d405add903 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/other-side.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Fixer.otherSide - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Fixer / otherSide
        +
        +

        otherSide

        + +val otherSide: Party
        +Overrides Secondary.otherSide
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/progress-tracker.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/progress-tracker.html index 33f8c3fd18..a63acc54c2 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/progress-tracker.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/progress-tracker.html @@ -8,7 +8,7 @@

        progressTracker

        -open val progressTracker: ProgressTracker
        +val progressTracker: ProgressTracker
        Overrides Secondary.progressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/session-i-d.html new file mode 100644 index 0000000000..fd38c048c4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/session-i-d.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Fixer.sessionID - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Fixer / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +Overrides Secondary.sessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/validate-handshake.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/validate-handshake.html index 8455853d0d..b7d1c399a3 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/validate-handshake.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixer/validate-handshake.html @@ -8,7 +8,7 @@

        validateHandshake

        -protected open fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef>
        +protected fun validateHandshake(handshake: Handshake<StateRef>): Handshake<StateRef>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-init-.html new file mode 100644 index 0000000000..5feb5958c7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-init-.html @@ -0,0 +1,21 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.<init> - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / <init>
        +
        +

        <init>

        +FixingRoleDecider(ref: StateRef, timeout: Duration, progressTracker: ProgressTracker = tracker(ref.toString()))
        +

        This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing.

        +

        It is kicked off as an activity on both participant nodes by the scheduler when its time for a fixing. If the +Fixer role is chosen, then that will be initiated by the FixingSessionInitiation message sent from the other party and +handled by the FixingSessionInitiationHandler.

        +

        TODO: Replace FixingSessionInitiation and FixingSessionInitiationHandler with generic session initiation logic once it exists.

        +
        +
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/-init-.html new file mode 100644 index 0000000000..7f9e377edc --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/-init-.html @@ -0,0 +1,14 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.LOADING.<init> - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / LOADING / <init>
        +
        +

        <init>

        +LOADING(ref: String)
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/index.html new file mode 100644 index 0000000000..94ab051357 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/-l-o-a-d-i-n-g/index.html @@ -0,0 +1,53 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.LOADING - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / LOADING
        +
        +

        LOADING

        +class LOADING : Step
        +
        +
        +

        Constructors

        + + + + + + + +
        +<init> +LOADING(ref: String)
        +

        Inherited Properties

        + + + + + + + + + + + +
        +changes +open val changes: <ERROR CLASS><Change>
        +label +open val label: String
        +

        Inherited Functions

        + + + + + + + +
        +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/call.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/call.html new file mode 100644 index 0000000000..99992db987 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/call.html @@ -0,0 +1,17 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.call - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / call
        +
        +

        call

        + +fun call(): Unit
        +Overrides ProtocolLogic.call
        +

        This is where you fill out your business logic.

        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/index.html new file mode 100644 index 0000000000..16be54e476 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/index.html @@ -0,0 +1,154 @@ + + +TwoPartyDealProtocol.FixingRoleDecider - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider
        +
        +

        FixingRoleDecider

        +class FixingRoleDecider : ProtocolLogic<Unit>
        +

        This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing.

        +

        It is kicked off as an activity on both participant nodes by the scheduler when its time for a fixing. If the +Fixer role is chosen, then that will be initiated by the FixingSessionInitiation message sent from the other party and +handled by the FixingSessionInitiationHandler.

        +

        TODO: Replace FixingSessionInitiation and FixingSessionInitiationHandler with generic session initiation logic once it exists.

        +
        +
        +
        +
        +

        Types

        + + + + + + + +
        +LOADING +class LOADING : Step
        +

        Constructors

        + + + + + + + +
        +<init> +FixingRoleDecider(ref: StateRef, timeout: Duration, progressTracker: ProgressTracker = tracker(ref.toString()))

        This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing.

        +
        +

        Properties

        + + + + + + + + + + + + + + + +
        +progressTracker +val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

        +
        +ref +val ref: StateRef
        +timeout +val timeout: Duration
        +

        Inherited Properties

        + + + + + + + + + + + + + + + +
        +logger +val logger: <ERROR CLASS>

        This is where you should log things to.

        +
        +psm +lateinit var psm: ProtocolStateMachine<*>

        Reference to the Fiber instance that is the top level controller for the entire flow.

        +
        +serviceHub +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        +
        +

        Functions

        + + + + + + + +
        +call +fun call(): Unit

        This is where you fill out your business logic.

        +
        +

        Inherited Functions

        + + + + + + + + + + + + + + + + + + + +
        +receive +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
        +send +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
        +sendAndReceive +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T>
        +subProtocol +fun <R> subProtocol(subLogic: ProtocolLogic<R>): R

        Invokes the given subprotocol by simply passing through this ProtocolLogics reference to the +ProtocolStateMachine and then calling the call method.

        +
        +

        Companion Object Functions

        + + + + + + + +
        +tracker +fun tracker(ref: String): ProgressTracker
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/progress-tracker.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/progress-tracker.html new file mode 100644 index 0000000000..4ba805a381 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/progress-tracker.html @@ -0,0 +1,24 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.progressTracker - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / progressTracker
        +
        +

        progressTracker

        + +val progressTracker: ProgressTracker
        +Overrides ProtocolLogic.progressTracker
        +

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

        +

        Note that this has to return a tracker before the protocol is invoked. You cant change your mind half way +through.

        +
        +
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/ref.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/ref.html new file mode 100644 index 0000000000..a0c74f6677 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/ref.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.ref - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / ref
        +
        +

        ref

        + +val ref: StateRef
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/timeout.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/timeout.html new file mode 100644 index 0000000000..06b1a050bb --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/timeout.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.timeout - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / timeout
        +
        +

        timeout

        + +val timeout: Duration
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/tracker.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/tracker.html new file mode 100644 index 0000000000..4c649b257b --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-role-decider/tracker.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingRoleDecider.tracker - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingRoleDecider / tracker
        +
        +

        tracker

        + +fun tracker(ref: String): ProgressTracker
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/-init-.html new file mode 100644 index 0000000000..454587952e --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/-init-.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation.<init> - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation / <init>
        +
        +

        <init>

        +FixingSessionInitiation(sessionID: Long, party: Party, sender: Party, timeout: Duration)
        +

        Used to set up the session between Floater and Fixer

        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/index.html new file mode 100644 index 0000000000..6bfd8781bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/index.html @@ -0,0 +1,56 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation
        +
        +

        FixingSessionInitiation

        +data class FixingSessionInitiation
        +

        Used to set up the session between Floater and Fixer

        +
        +
        +

        Constructors

        + + + + + + + +
        +<init> +FixingSessionInitiation(sessionID: Long, party: Party, sender: Party, timeout: Duration)

        Used to set up the session between Floater and Fixer

        +
        +

        Properties

        + + + + + + + + + + + + + + + + + + + +
        +party +val party: Party
        +sender +val sender: Party
        +sessionID +val sessionID: Long
        +timeout +val timeout: Duration
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/party.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/party.html new file mode 100644 index 0000000000..8a33b57054 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/party.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation.party - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation / party
        +
        +

        party

        + +val party: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/sender.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/sender.html new file mode 100644 index 0000000000..18c06ea640 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/sender.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation.sender - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation / sender
        +
        +

        sender

        + +val sender: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/session-i-d.html new file mode 100644 index 0000000000..d6d1b6c660 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/session-i-d.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation.sessionID - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation / sessionID
        +
        +

        sessionID

        + +val sessionID: Long
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/timeout.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/timeout.html new file mode 100644 index 0000000000..fa02141b99 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-fixing-session-initiation/timeout.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.FixingSessionInitiation.timeout - + + + +com.r3corda.protocols / TwoPartyDealProtocol / FixingSessionInitiation / timeout
        +
        +

        timeout

        + +val timeout: Duration
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/-init-.html index 62a0e13462..bbef5b3954 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Floater / <init>

        <init>

        -Floater(otherSide: SingleMessageRecipient, otherSessionID: Long, notary: NodeInfo, dealToFix: StateAndRef<T>, myKeyPair: KeyPair, sessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
        +Floater(payload: StateRef, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        As per the Fixer, do not infer too much from this class name in terms of business roles. This is just the "side" of the protocol run by the party with the floating leg as a way of deciding who diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/index.html index 4bb3535716..e6eddcfe2e 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/index.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Floater

        Floater

        -class Floater<T : FixableDealState> : Primary<StateRef>
        +class Floater : Primary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        As per the Fixer, do not infer too much from this class name in terms of business roles. This is just the "side" of the protocol run by the party with the floating leg as a way of deciding who @@ -23,7 +23,7 @@ does what in the protocol.

        <init> -Floater(otherSide: SingleMessageRecipient, otherSessionID: Long, notary: NodeInfo, dealToFix: StateAndRef<T>, myKeyPair: KeyPair, sessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        +Floater(payload: StateRef, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        @@ -33,54 +33,43 @@ does what in the protocol.

        -progressTracker - -open val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something -helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the -tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track -progress.

        - - - - -sessionID - -val sessionID: Long - - - -

        Inherited Properties

        - - - - +myKeyPair +notaryNode +otherSessionID +otherSide +val otherSide: Party +payload +val payload: StateRef + + + +
        -myKeyPair val myKeyPair: KeyPair
        -notaryNode val notaryNode: NodeInfo
        -otherSessionID val otherSessionID: Long
        -otherSide -val otherSide: SingleMessageRecipient
        -payload -val payload: U
        +progressTracker +val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

        +
        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/my-key-pair.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/my-key-pair.html new file mode 100644 index 0000000000..464d66d738 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/my-key-pair.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Floater.myKeyPair - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Floater / myKeyPair
        +
        +

        myKeyPair

        + +val myKeyPair: KeyPair
        +Overrides Primary.myKeyPair
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/notary-node.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/notary-node.html new file mode 100644 index 0000000000..af61914e72 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/notary-node.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Floater.notaryNode - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Floater / notaryNode
        +
        +

        notaryNode

        + +val notaryNode: NodeInfo
        +Overrides Primary.notaryNode
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-session-i-d.html new file mode 100644 index 0000000000..e062563a0a --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-session-i-d.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Floater.otherSessionID - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Floater / otherSessionID
        +
        +

        otherSessionID

        + +val otherSessionID: Long
        +Overrides Primary.otherSessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-side.html new file mode 100644 index 0000000000..c47e99850c --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/other-side.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Floater.otherSide - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Floater / otherSide
        +
        +

        otherSide

        + +val otherSide: Party
        +Overrides Primary.otherSide
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/payload.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/payload.html new file mode 100644 index 0000000000..4df7541209 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/payload.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Floater.payload - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Floater / payload
        +
        +

        payload

        + +val payload: StateRef
        +Overrides Primary.payload
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/progress-tracker.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/progress-tracker.html index c4419152a7..a780ac13ea 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/progress-tracker.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-floater/progress-tracker.html @@ -8,7 +8,7 @@

        progressTracker

        -open val progressTracker: ProgressTracker
        +val progressTracker: ProgressTracker
        Overrides Primary.progressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/-init-.html index 11d9d64d5f..c8b5bb5929 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Instigator / <init>

        <init>

        -Instigator(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, dealBeingOffered: T, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
        +Instigator(otherSide: Party, notary: Party, payload: T, myKeyPair: KeyPair, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the protocol for inserting a pre-agreed deal.



        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/index.html index 1b876b151f..5061804d91 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/index.html @@ -18,7 +18,7 @@ <init> -Instigator(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, dealBeingOffered: T, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the protocol for inserting a pre-agreed deal.

        +Instigator(otherSide: Party, notary: Party, payload: T, myKeyPair: KeyPair, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())

        One side of the protocol for inserting a pre-agreed deal.

        @@ -28,6 +28,42 @@ +myKeyPair + +open val myKeyPair: KeyPair + + + +notary + +val notary: Party + + + +notaryNode + +open val notaryNode: NodeInfo + + + +otherSessionID + +open val otherSessionID: Long + + + +otherSide + +open val otherSide: Party + + + +payload + +open val payload: T + + + progressTracker open val progressTracker: ProgressTracker

        Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something @@ -38,41 +74,6 @@ progress.

        -

        Inherited Properties

        - - - - - - - - - - - - - - - - - - - - - - - -
        -myKeyPair -val myKeyPair: KeyPair
        -notaryNode -val notaryNode: NodeInfo
        -otherSessionID -val otherSessionID: Long
        -otherSide -val otherSide: SingleMessageRecipient
        -payload -val payload: U

        Inherited Functions

        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/my-key-pair.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/my-key-pair.html new file mode 100644 index 0000000000..0aa8dac5c4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/my-key-pair.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Instigator.myKeyPair - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / myKeyPair
        +
        +

        myKeyPair

        + +open val myKeyPair: KeyPair
        +Overrides Primary.myKeyPair
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary-node.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary-node.html new file mode 100644 index 0000000000..cd84317de2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary-node.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Instigator.notaryNode - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / notaryNode
        +
        +

        notaryNode

        + +open val notaryNode: NodeInfo
        +Overrides Primary.notaryNode
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary.html new file mode 100644 index 0000000000..9886189510 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/notary.html @@ -0,0 +1,15 @@ + + +TwoPartyDealProtocol.Instigator.notary - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / notary
        +
        +

        notary

        + +val notary: Party
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-session-i-d.html new file mode 100644 index 0000000000..5d557604bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-session-i-d.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Instigator.otherSessionID - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / otherSessionID
        +
        +

        otherSessionID

        + +open val otherSessionID: Long
        +Overrides Primary.otherSessionID
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-side.html new file mode 100644 index 0000000000..4584fcae3d --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/other-side.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Instigator.otherSide - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / otherSide
        +
        +

        otherSide

        + +open val otherSide: Party
        +Overrides Primary.otherSide
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/payload.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/payload.html new file mode 100644 index 0000000000..232e51a601 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-instigator/payload.html @@ -0,0 +1,16 @@ + + +TwoPartyDealProtocol.Instigator.payload - + + + +com.r3corda.protocols / TwoPartyDealProtocol / Instigator / payload
        +
        +

        payload

        + +open val payload: T
        +Overrides Primary.payload
        +
        +
        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/-init-.html index 1518b31109..c93ec61e33 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Primary / <init>

        <init>

        -Primary(payload: U, otherSide: SingleMessageRecipient, otherSessionID: Long, myKeyPair: KeyPair, notaryNode: NodeInfo, progressTracker: ProgressTracker = Primary.tracker())
        +Primary(progressTracker: ProgressTracker = Primary.tracker())

        Abstracted bilateral deal protocol participant that initiates communication/handshake.

        Theres a good chance we can push at least some of this logic down into core protocol logic and helper methods etc.

        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/index.html index 0661879436..670f42ecef 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/index.html @@ -69,7 +69,7 @@ and helper methods etc.

        @@ -81,31 +81,31 @@ and helper methods etc.

        +abstract val myKeyPair: KeyPair +abstract val notaryNode: NodeInfo +abstract val otherSessionID: Long +abstract val otherSide: Party +abstract val payload: U @@ -182,20 +184,20 @@ progress.

        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T> +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/my-key-pair.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/my-key-pair.html index e7b70fcb20..c94f0a621f 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/my-key-pair.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/my-key-pair.html @@ -8,7 +8,7 @@

        myKeyPair

        -val myKeyPair: KeyPair
        +abstract val myKeyPair: KeyPair


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/notary-node.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/notary-node.html index 6d7aa9f5b4..08ddd62297 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/notary-node.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/notary-node.html @@ -8,7 +8,7 @@

        notaryNode

        -val notaryNode: NodeInfo
        +abstract val notaryNode: NodeInfo


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-session-i-d.html index 3d70279932..a2461eed60 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-session-i-d.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-session-i-d.html @@ -8,7 +8,7 @@

        otherSessionID

        -val otherSessionID: Long
        +abstract val otherSessionID: Long


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-side.html index bc504c33f7..595f90926b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -val otherSide: SingleMessageRecipient
        +abstract val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/payload.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/payload.html index d13eb47669..7227e9f884 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/payload.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-primary/payload.html @@ -8,7 +8,7 @@

        payload

        -val payload: U
        +abstract val payload: U


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/-init-.html index 96a6112082..bd12a06009 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyDealProtocol / Secondary / <init>

        <init>

        -Secondary(otherSide: SingleMessageRecipient, notary: Party, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
        +Secondary(progressTracker: ProgressTracker = Secondary.tracker())

        Abstracted bilateral deal protocol participant that is recipient of initial communication.

        Theres a good chance we can push at least some of this logic down into core protocol logic and helper methods etc.

        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/index.html index 523de25156..47e4729817 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/index.html @@ -57,7 +57,7 @@ and helper methods etc.

        @@ -67,15 +67,9 @@ and helper methods etc.

        - - - - +abstract val otherSide: Party +abstract val sessionID: Long
        <init> -Primary(payload: U, otherSide: SingleMessageRecipient, otherSessionID: Long, myKeyPair: KeyPair, notaryNode: NodeInfo, progressTracker: ProgressTracker = Primary.tracker())

        Abstracted bilateral deal protocol participant that initiates communication/handshake.

        +Primary(progressTracker: ProgressTracker = Primary.tracker())

        Abstracted bilateral deal protocol participant that initiates communication/handshake.

        myKeyPair -val myKeyPair: KeyPair
        notaryNode -val notaryNode: NodeInfo
        otherSessionID -val otherSessionID: Long
        otherSide -val otherSide: SingleMessageRecipient
        payload -val payload: U
        @@ -140,7 +140,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        receive -fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
        -fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
        send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit
        sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T>
        @@ -225,7 +227,7 @@ progress.

        Floater -class Floater<T : FixableDealState> : Primary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        +class Floater : Primary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        <init> -Secondary(otherSide: SingleMessageRecipient, notary: Party, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())

        Abstracted bilateral deal protocol participant that is recipient of initial communication.

        +Secondary(progressTracker: ProgressTracker = Secondary.tracker())

        Abstracted bilateral deal protocol participant that is recipient of initial communication.

        -notary -val notary: Party
        otherSide -val otherSide: SingleMessageRecipient
        @@ -91,7 +85,7 @@ progress.

        sessionID -val sessionID: Long
        @@ -116,7 +110,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -159,13 +155,13 @@ progress.

        send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> @@ -202,7 +198,7 @@ progress.

        Fixer -class Fixer<T : FixableDealState> : Secondary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        +class Fixer : Secondary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/other-side.html index 11afc2a59a..8c4a359e84 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -val otherSide: SingleMessageRecipient
        +abstract val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/session-i-d.html index 9ddba69295..bf371642bd 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/session-i-d.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/-secondary/session-i-d.html @@ -8,7 +8,7 @@

        sessionID

        -val sessionID: Long
        +abstract val sessionID: Long


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/index.html index babad0437d..88bc1a28e3 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-deal-protocol/index.html @@ -11,6 +11,7 @@

        Classes for manipulating a two party deal or agreement.

        TODO: The subclasses should probably be broken out into individual protocols rather than making this an ever expanding collection of subclasses.

        TODO: Also, the term Deal is used here where we might prefer Agreement.

        +

        TODO: Consider whether we can merge this with TwoPartyTradeProtocol




        @@ -29,14 +30,28 @@ Fixer -class Fixer<T : FixableDealState> : Secondary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        +class Fixer : Secondary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised further.

        + + + + +FixingRoleDecider + +class FixingRoleDecider : ProtocolLogic<Unit>

        This protocol looks at the deal and decides whether to be the Fixer or Floater role in agreeing a fixing.

        + + + + +FixingSessionInitiation + +data class FixingSessionInitiation

        Used to set up the session between Floater and Fixer

        Floater -class Floater<T : FixableDealState> : Primary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        +class Floater : Primary<StateRef>

        One side of the fixing protocol for an interest rate swap, but could easily be generalised furher

        @@ -100,6 +115,13 @@ val DEAL_TOPIC: String + + +FIX_INITIATE_TOPIC + +val FIX_INITIATE_TOPIC: String

        This topic exists purely for FixingSessionInitiation to be sent from FixingRoleDecider to FixingSessionInitiationHandler

        + + diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/-init-.html index d5b8dcf697..42f6a1c778 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyTradeProtocol / Buyer / <init>

        <init>

        -Buyer(otherSide: SingleMessageRecipient, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>, sessionID: Long)
        +Buyer(otherSide: Party, notary: Party, acceptablePrice: Amount<Issued<Currency>>, typeToBuy: Class<out OwnableState>, sessionID: Long)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/acceptable-price.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/acceptable-price.html index e1a2083a67..7ba69e7380 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/acceptable-price.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/acceptable-price.html @@ -8,7 +8,7 @@

        acceptablePrice

        -val acceptablePrice: Amount<Currency>
        +val acceptablePrice: Amount<Issued<Currency>>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/index.html index 9e6e88bf08..05a4e72b6b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/index.html @@ -46,7 +46,7 @@ <init> -Buyer(otherSide: SingleMessageRecipient, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>, sessionID: Long) +Buyer(otherSide: Party, notary: Party, acceptablePrice: Amount<Issued<Currency>>, typeToBuy: Class<out OwnableState>, sessionID: Long) @@ -57,7 +57,7 @@ acceptablePrice -val acceptablePrice: Amount<Currency> +val acceptablePrice: Amount<Issued<Currency>> @@ -69,7 +69,7 @@ otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party @@ -116,7 +116,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -147,13 +149,13 @@ progress.

        send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/other-side.html index 30088a885a..fa91b79a4e 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-buyer/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -val otherSide: SingleMessageRecipient
        +val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/-init-.html index b3cc785c84..689672cbf2 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyTradeProtocol / SellerTradeInfo / <init>

        <init>

        -SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Currency>, sellerOwnerKey: PublicKey, sessionID: Long)
        +SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, sellerOwnerKey: PublicKey, sessionID: Long)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/index.html index d3d152ecbb..43c71824c3 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/index.html @@ -17,7 +17,7 @@ <init> -SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Currency>, sellerOwnerKey: PublicKey, sessionID: Long) +SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, sellerOwnerKey: PublicKey, sessionID: Long) @@ -34,7 +34,7 @@ price -val price: Amount<Currency> +val price: Amount<Issued<Currency>> diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/price.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/price.html index 84ec81d400..9ecd3cdb4b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/price.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller-trade-info/price.html @@ -8,7 +8,7 @@

        price

        -val price: Amount<Currency>
        +val price: Amount<Issued<Currency>>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/-init-.html index 4e85346803..d385bb3b43 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyTradeProtocol / Seller / <init>

        <init>

        -Seller(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Currency>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())
        +Seller(otherSide: Party, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/index.html index 73f32472d1..5c6f54067d 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/index.html @@ -52,7 +52,7 @@ <init> -Seller(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Currency>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker()) +Seller(otherSide: Party, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker()) @@ -87,13 +87,13 @@ otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party price -val price: Amount<Currency> +val price: Amount<Issued<Currency>> @@ -128,7 +128,9 @@ progress.

        serviceHub -val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts

        +val serviceHub: ServiceHub

        Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

        @@ -165,13 +167,13 @@ progress.

        send -fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any): Unit +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit sendAndReceive -fun <T : Any> sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any): UntrustworthyData<T> +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/other-side.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/other-side.html index e9ee3bbb75..2888cdfb72 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/other-side.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/other-side.html @@ -8,7 +8,7 @@

        otherSide

        -val otherSide: SingleMessageRecipient
        +val otherSide: Party


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/price.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/price.html index b0d265cb45..5e91b02f9b 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/price.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-seller/price.html @@ -8,7 +8,7 @@

        price

        -val price: Amount<Currency>
        +val price: Amount<Issued<Currency>>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/-init-.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/-init-.html index 1ef7a02902..a091a830a5 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / TwoPartyTradeProtocol / UnacceptablePriceException / <init>

        <init>

        -UnacceptablePriceException(givenPrice: Amount<Currency>)
        +UnacceptablePriceException(givenPrice: Amount<Issued<Currency>>)


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/given-price.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/given-price.html index 8c15078950..9d05c61721 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/given-price.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/given-price.html @@ -8,7 +8,7 @@

        givenPrice

        -val givenPrice: Amount<Currency>
        +val givenPrice: Amount<Issued<Currency>>


        diff --git a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/index.html b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/index.html index e27ae2f1e3..433ec403d0 100644 --- a/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-two-party-trade-protocol/-unacceptable-price-exception/index.html @@ -17,7 +17,7 @@ <init> -UnacceptablePriceException(givenPrice: Amount<Currency>) +UnacceptablePriceException(givenPrice: Amount<Issued<Currency>>) @@ -28,7 +28,7 @@ givenPrice -val givenPrice: Amount<Currency> +val givenPrice: Amount<Issued<Currency>> diff --git a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/-init-.html index 8d5d76caa4..1f554c88d0 100644 --- a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/-init-.html +++ b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/-init-.html @@ -7,7 +7,7 @@ com.r3corda.protocols / ValidatingNotaryProtocol / <init>

        <init>

        -ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
        +ValidatingNotaryProtocol(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A notary commit protocol that makes sure a given transaction is valid before committing it. This does mean that the calling party has to reveal the whole transaction history; however, we avoid complex conflict resolution logic where a party has its input states "blocked" by a transaction from another party, and needs to establish whether that transaction was diff --git a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/before-commit.html b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/before-commit.html index eb68331e99..91af00cc44 100644 --- a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/before-commit.html +++ b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/before-commit.html @@ -7,8 +7,8 @@ com.r3corda.protocols / ValidatingNotaryProtocol / beforeCommit

        beforeCommit

        - -fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
        + +fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit
        Overrides Service.beforeCommit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully resolving it into a TransactionForVerification, for which the caller would have to reveal the whole transaction diff --git a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/index.html index d9ee826e6b..13e1f6b4ba 100644 --- a/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-validating-notary-protocol/index.html @@ -21,7 +21,7 @@ indeed valid

        <init> -ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A notary commit protocol that makes sure a given transaction is valid before committing it. This does mean that the calling +ValidatingNotaryProtocol(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)

        A notary commit protocol that makes sure a given transaction is valid before committing it. This does mean that the calling party has to reveal the whole transaction history; however, we avoid complex conflict resolution logic where a party has its input states "blocked" by a transaction from another party, and needs to establish whether that transaction was indeed valid

        @@ -36,7 +36,7 @@ indeed valid

        otherSide -val otherSide: SingleMessageRecipient +val otherSide: Party @@ -71,7 +71,7 @@ indeed valid

        beforeCommit -fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully +fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit

        No pre-commit processing is done. Transaction is not checked for contract-validity, as that would require fully resolving it into a TransactionForVerification, for which the caller would have to reveal the whole transaction history chain. As a result, the Notary will commit invalid transactions as well, but as it also records the identity of diff --git a/docs/build/html/api/com.r3corda.protocols/index.html b/docs/build/html/api/com.r3corda.protocols/index.html index 297b9f4842..d2e75c1af2 100644 --- a/docs/build/html/api/com.r3corda.protocols/index.html +++ b/docs/build/html/api/com.r3corda.protocols/index.html @@ -14,9 +14,7 @@ AbstractRequestMessage -abstract class AbstractRequestMessage

        Abstract superclass for request messages sent to services, which includes common -fields such as replyTo and replyToTopic.

        - +abstract class AbstractRequestMessage : ServiceRequestMessage @@ -73,6 +71,14 @@ all the transactions have been successfully verified and inserted into the local +ServiceRequestMessage + +interface ServiceRequestMessage

        Abstract superclass for request messages sent to services, which includes common +fields such as replyTo and replyToTopic.

        + + + + TwoPartyDealProtocol object TwoPartyDealProtocol

        Classes for manipulating a two party deal or agreement.

        diff --git a/docs/build/html/api/index-outline.html b/docs/build/html/api/index-outline.html index 4abfafadb5..47fae3e3ca 100644 --- a/docs/build/html/api/index-outline.html +++ b/docs/build/html/api/index-outline.html @@ -56,13 +56,14 @@ abstract fun buildTransaction(type: ContractDefRef, steps: List<TransactionBuildStep>): SerializedBytes<WireTransaction>
        abstract fun commitTransaction(tx: SerializedBytes<WireTransaction>, signatures: List<WithKey>): SecureHash
        abstract fun fetchProtocolsRequiringAttention(query: StatesQuery): Map<StateRef, ProtocolRequiringAttention>
        -abstract fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
        +abstract fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?>
        abstract fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?>
        abstract fun generateTransactionSignature(tx: SerializedBytes<WireTransaction>): WithKey
        abstract fun invokeProtocolSync(type: ProtocolRef, args: Map<String, Any?>): Any?
        abstract fun provideProtocolResponse(protocol: ProtocolInstanceRef, choice: SecureHash, args: Map<String, Any?>): Unit
        abstract fun queryStates(query: StatesQuery): List<StateRef>
        abstract fun serverTime(): LocalDateTime
        +abstract fun status(): <ERROR CLASS>
      @@ -78,7 +79,7 @@ fun buildTransaction(type: ContractDefRef, steps: List<TransactionBuildStep>): SerializedBytes<WireTransaction>
      fun commitTransaction(tx: SerializedBytes<WireTransaction>, signatures: List<WithKey>): SecureHash
      fun fetchProtocolsRequiringAttention(query: StatesQuery): Map<StateRef, ProtocolRequiringAttention>
      -fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
      +fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?>
      fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?>
      fun generateTransactionSignature(tx: SerializedBytes<WireTransaction>): WithKey
      fun invokeProtocolSync(type: ProtocolRef, args: Map<String, Any?>): Any?
      @@ -86,6 +87,7 @@ fun provideProtocolResponse(protocol: ProtocolInstanceRef, choice: SecureHash, args: Map<String, Any?>): Unit
      fun queryStates(query: StatesQuery): List<StateRef>
      fun serverTime(): LocalDateTime
      +fun status(): <ERROR CLASS>
    @@ -106,14 +108,15 @@ lateinit var checkpointStorage: CheckpointStorage
    val configuration: NodeConfiguration
    protected open fun constructStorageService(attachments: NodeAttachmentService, transactionStorage: TransactionStorage, keypair: KeyPair, identity: Party): StorageServiceImpl
    +protected fun createNodeDir(): Unit
    val dir: Path
    open fun findMyLocation(): PhysicalLocation?
    -protected open fun generateKeyPair(): KeyPair
    +protected open fun generateKeyPair(): <ERROR CLASS>
    lateinit var identity: IdentityService
    var inNodeNetworkMapService: NetworkMapService?
    var inNodeNotaryService: NotaryService?
    val info: NodeInfo
    -protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage>
    +protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage>
    lateinit var interestRatesService: Service
    var isPreviousCheckpointsPresent: Boolean
    lateinit var keyManagement: E2ETestKeyManagementService
    @@ -130,20 +133,22 @@ val networkMapService: NodeInfo?
    protected open fun noNetworkMapConfigured(): <ERROR CLASS><Unit>
    val platformClock: Clock
    +lateinit var scheduler: SchedulerService
    protected abstract val serverThread: AffinityExecutor
    val services: ServiceHubInternal
    val servicesThatAcceptUploads: List<AcceptsFileUpload>
    +open fun setup(): AbstractNode
    lateinit var smm: StateMachineManager
    open fun start(): AbstractNode
    protected abstract fun startMessagingService(): Unit
    var started: Boolean
    open fun stop(): Unit
    -lateinit var storage: StorageService
    +lateinit var storage: TxWritableStorageService
    lateinit var wallet: WalletService
-abstract class AbstractNodeService
+abstract class AbstractNodeService : SingletonSerializeAsToken
-abstract class AbstractRequestMessage
+abstract class AbstractRequestMessage : ServiceRequestMessage
+abstract class AbstractStateReplacementProtocol<T>
+ @@ -181,16 +286,21 @@ AbstractTransactionForTest()
-fun arg(vararg key: PublicKey, c: () -> CommandData): Unit
+fun addCommand(cmd: Command): Unit
+fun arg(vararg keys: PublicKey, c: () -> CommandData): Unit
+fun arg(key: PublicKey, c: CommandData): Unit
fun attachment(attachmentID: SecureHash): Unit
protected val attachments: ArrayList<SecureHash>
protected val commands: ArrayList<Command>
protected fun commandsToAuthenticatedObjects(): List<AuthenticatedObject<CommandData>>
protected val outStates: ArrayList<LabeledOutput>
open fun output(label: String? = null, s: () -> ContractState): <ERROR CLASS>
+open fun output(label: String? = null, s: ContractState): <ERROR CLASS>
+protected val signers: LinkedHashSet<PublicKey>
fun timestamp(time: Instant): Unit
fun timestamp(data: TimestampCommand): Unit
-fun transaction(body: TransactionForTest.() -> Unit): Unit
+fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): Unit
+protected val type: General
@@ -221,6 +331,7 @@ +object Ack : DeserializeAsKotlinObjectDef
enum class AddOrRemove
    @@ -283,6 +394,20 @@
interface AllPossibleRecipients : MessageRecipients
+class AlwaysSucceedContract : Contract
+ data class Amount<T> : Comparable<Amount<T>>
    @@ -306,6 +431,20 @@
+data class AppContext
+ class ArtemisMessagingService : SingletonSerializeAsToken, MessagingService
    @@ -348,19 +487,6 @@
-interface AssetIssuanceDefinition<T> : IssuanceDefinition
- interface Attachment : NamedByHash
@@ -509,7 +636,7 @@ -class Requester<T> : ProtocolLogic<SignedTransaction>
+class Requester : ProtocolLogic<SignedTransaction>
    @@ -544,6 +671,19 @@
+interface BilateralNettableState<T : BilateralNettableState<T>>
+ class BriefLogFormatter : Formatter
    @@ -599,7 +739,7 @@
-class Cash : FungibleAsset<Currency>
+class Cash : FungibleAsset<Currency>
@@ -753,6 +884,107 @@ +sealed class CliParams
+ +object CliParamsSpec
+ data class Command
-fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party): TransactionBuilder
+fun generateIssue(faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKey): Unit
-fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit
+fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit
val legalContractReference: SecureHash
-fun verify(tx: TransactionForVerification): Unit
+fun verify(tx: TransactionForContract): Unit
@@ -895,7 +1127,7 @@ abstract val legalContractReference: SecureHash
-abstract fun verify(tx: TransactionForVerification): Unit
+abstract fun verify(tx: TransactionForContract): Unit
@@ -935,7 +1167,7 @@ abstract val contract: Contract
-abstract val notary: Party
+abstract val participants: List<PublicKey>
@@ -974,24 +1206,11 @@ -DataVendingService(net: MessagingService, storage: StorageService)
+DataVendingService(net: MessagingService, storage: StorageService, networkMapCache: NetworkMapCache)
val logger: <ERROR CLASS>
-enum class DateOffset
- enum class DateRollConvention
+interface DeserializeAsKotlinObjectDef
open class DigitalSignature : OpaqueBytes
    @@ -1232,10 +1452,7 @@
- - - -class State : ContractState
+class Move : TypeOnlyCommandData, Commands
+ + + +data class MultiOwnerState : ContractState, State
+ +data class SingleOwnerState : OwnableState, State
+ +interface State : ContractState
+ fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder
val legalContractReference: SecureHash
-fun verify(tx: TransactionForVerification): Unit
+fun verify(tx: TransactionForContract): Unit
+ + + +class DummyLinearState : LinearState
+ @@ -1276,6 +1555,21 @@ +data class DummyState : ContractState
+ class E2ETestKeyManagementService : SingletonSerializeAsToken, KeyManagementService
+object Ed25519PrivateKeySerializer
+ +object Ed25519PublicKeySerializer
+ object Emoji
+object FixingSessionInitiationHandler
+ open class FloatingRate : Rate
    @@ -1755,7 +2090,7 @@
-abstract class FungibleAsset<T> : Contract
+abstract class FungibleAsset<T> : Contract
-interface State<T> : FungibleAssetState<T, AssetIssuanceDefinition<T>>
+interface FungibleAssetState<T, I> : OwnableState
-open fun verify(tx: TransactionForVerification): Unit
- - - -interface FungibleAssetState<T, I : AssetIssuanceDefinition<T>> : OwnableState
+enum class IRSDemoNode
@@ -1858,7 +2195,7 @@ -IRSSimulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)
+IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)
fun iterate(): MessageTransfer?
val om: <ERROR CLASS>
protected fun startMainSimulation(): <ERROR CLASS><Unit>
@@ -1879,6 +2216,18 @@ +class IllegalProtocolLogicException : IllegalArgumentException
+ class ImmutableClassSerializer<T : Any>
-class InsufficientBalanceException : Exception
+open class InMemoryWalletService : SingletonSerializeAsToken, WalletService
+class InsufficientBalanceException : Exception
+ @@ -2290,11 +2672,11 @@ -FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriod: DateOffset, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)
-fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: DateOffset = this.fixingPeriod, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg
+FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriodOffset: Int, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)
+fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: Int = this.fixingPeriodOffset, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg
open fun equals(other: Any?): Boolean
var fixingCalendar: BusinessCalendar
-var fixingPeriod: DateOffset
+var fixingPeriodOffset: Int
var fixingRollConvention: DateRollConvention
var fixingsPerPayment: Frequency
var floatingRatePayer: Party
@@ -2309,7 +2691,7 @@ -data class State : FixableDealState
+data class State : FixableDealState, SchedulableState
@@ -2393,6 +2776,115 @@ interface IssuanceDefinition
+interface IssueCommand : CommandData
+ +data class Issued<P>
+ +object JavaTestHelpers
+ +object JavaTestHelpers
+ +object JavaTestHelpers
+ object JsonSupport
    @@ -2461,6 +2953,30 @@
+object PublicKeyDeserializer
+ +object PublicKeySerializer
+ class SecureHashDeserializer<T : SecureHash>
    @@ -2530,6 +3046,19 @@
+object KotlinObjectSerializer
+ class LabeledOutput
+sealed class LastLineShouldTestForAcceptOrFailure
data class LedgerTransaction : NamedByHash
@@ -2707,7 +3239,7 @@ -MockNetwork(threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)
+MockNetwork(networkSendManuallyPumped: Boolean = false, threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)
object DefaultFactory : Factory
    @@ -2799,7 +3331,7 @@
-class MockStorageService : SingletonSerializeAsToken, StorageService
+class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService
    @@ -2842,6 +3374,18 @@
+interface MoveCommand : CommandData
+ abstract class MutableClock : Clock
    @@ -2869,6 +3413,19 @@
+enum class NetType
+ sealed class NetworkCacheError : Exception
val REGISTER_PROTOCOL_TOPIC: String
-class RegistrationRequest : AbstractRequestMessage
+class RegistrationRequest : NetworkMapRequestMessage
val SUBSCRIPTION_PROTOCOL_TOPIC: String
-class SubscribeRequest : AbstractRequestMessage
+class SubscribeRequest : NetworkMapRequestMessage
@@ -3258,10 +3835,11 @@ -Oracle(identity: Party, signingKey: KeyPair)
+Oracle(identity: Party, signingKey: KeyPair, clock: Clock)
+val clock: Clock
val identity: Party
var knownFixes: FixContainer
-fun query(queries: List<FixOf>): List<Fix>
+fun query(queries: List<FixOf>, deadline: Instant): List<Fix>
fun sign(wtx: WireTransaction): LegallyIdentifiable
@@ -3284,7 +3862,7 @@ object Type : ServiceType
-class UnknownFix : Exception
+class UnknownFix : RetryableException
@@ -3369,7 +3946,7 @@ -class NodeWalletService : SingletonSerializeAsToken, WalletService
+class NodeSchedulerService : SchedulerService, SingletonSerializeAsToken
+class NodeWalletService : InMemoryWalletService
+ @@ -3394,7 +3980,7 @@ -NonEmptySet(initial: T, set: MutableSet<T> = mutableSetOf())
+NonEmptySet(initial: T)
inner class Iterator<T, T> : MutableIterator<T>
    @@ -3428,6 +4014,89 @@
+object NonEmptySetSerializer
+ +object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>
+ +class NotaryChangeService : AbstractNodeService
+ sealed class NotaryError
    @@ -3475,6 +4144,19 @@
+class SignaturesMissing : NotaryError
+ class TimestampInvalid : NotaryError
@@ -3562,7 +4244,7 @@ -abstract fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
+abstract fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
@@ -3574,8 +4256,9 @@ -Handshake(replyTo: SingleMessageRecipient, sendSessionID: Long, sessionID: Long)
+Handshake(replyTo: Party, sendSessionID: Long, sessionID: Long)
val sendSessionID: Long
+val sessionID: Long
@@ -3602,10 +4285,10 @@ -Service(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
-open fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
+Service(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+open fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit
open fun call(): Unit
-val otherSide: SingleMessageRecipient
+val otherSide: Party
val receiveSessionID: Long
val sendSessionID: Long
val timestampChecker: TimestampChecker
@@ -3621,9 +4304,9 @@ -SignRequest(txBits: SerializedBytes<WireTransaction>, callerIdentity: Party)
+SignRequest(tx: SignedTransaction, callerIdentity: Party)
val callerIdentity: Party
-val txBits: SerializedBytes<WireTransaction>
+val tx: SignedTransaction
@@ -3640,7 +4323,7 @@ -NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
abstract val logger: <ERROR CLASS>
abstract val protocolFactory: Factory
@@ -3666,6 +4349,251 @@ +class Obligation<P> : Contract
+ open class OpaqueBytes
+data class ProtocolLogicRef
+ +class ProtocolLogicRefFactory : SingletonSerializeAsToken
+ interface ProtocolRef
data class ProtocolRequiringAttention
+interface ReadOnlyTransactionStorage
+ class RecordingMap<K, V> : MutableMap<K, V>
@@ -4567,7 +5637,7 @@ -SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
val logger: <ERROR CLASS>
val protocolFactory: DefaultFactory
@@ -4582,7 +5652,7 @@ -Simulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)
+Simulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)
inner class BankFactory : Factory
@@ -4770,7 +5842,7 @@ -FiberRequest(topic: String, destination: MessageRecipients?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?)
+FiberRequest(topic: String, destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any?)
class ExpectingResponse<R : Any> : FiberRequest
-val destination: MessageRecipients?
+val destination: Party?
val payload: Any?
val sessionIDForReceive: Long
val sessionIDForSend: Long
@@ -4844,6 +5916,35 @@ +class StateReplacementException : Exception
+ +class StateReplacementRefused
+ interface StatesQuery
-open class StorageServiceImpl : SingletonSerializeAsToken, StorageService
+open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService
    @@ -4958,7 +6059,7 @@
-class TestClock : MutableClock
+class TestClock : MutableClock, SerializeAsToken
@@ -4982,9 +6085,9 @@ -val keypair: KeyPair
-val keypair2: KeyPair
-val keypair3: KeyPair
+val keypair: <ERROR CLASS>
+val keypair2: <ERROR CLASS>
+val keypair3: <ERROR CLASS>
@@ -4996,13 +6099,29 @@ -ThreadBox(content: T, lock: Lock = ReentrantLock())
+ThreadBox(content: T, lock: ReentrantLock = ReentrantLock())
+inline fun <R> alreadyLocked(body: T.() -> R): R
val content: T
-val lock: Lock
+val lock: ReentrantLock
inline fun <R> locked(body: T.() -> R): R
+data class TimeWindow
+ class TimestampChecker
    @@ -5059,56 +6178,6 @@
-class TraderDemoProtocolBuyer : ProtocolLogic<Unit>
- -class TraderDemoProtocolSeller : ProtocolLogic<Unit>
- data class TransactionBuildStep
    @@ -5123,7 +6192,7 @@
-class TransactionBuilder
+abstract class TransactionBuilder
+data class TransactionForContract
+ open class TransactionForTest : AbstractTransactionForTest
@@ -5200,34 +6322,17 @@ -TransactionForVerification(inStates: List<ContractState>, outStates: List<ContractState>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash)
-data class InOutGroup<T : ContractState, K : Any>
- +TransactionForVerification(inputs: List<TransactionState<ContractState>>, outputs: List<TransactionState<ContractState>>, attachments: List<Attachment>, commands: List<AuthenticatedObject<CommandData>>, origHash: SecureHash, signers: List<PublicKey>, type: TransactionType)
val attachments: List<Attachment>
val commands: List<AuthenticatedObject<CommandData>>
fun equals(other: Any?): Boolean
-fun getTimestampBy(timestampingAuthority: Party): TimestampCommand?
-fun getTimestampByName(vararg authorityName: String): TimestampCommand?
-fun <T : ContractState, K : Any> groupStates(ofType: Class<T>, selector: (T) -> K): List<InOutGroup<T, K>>
-inline fun <reified T : ContractState, K : Any> groupStates(selector: (T) -> K): List<InOutGroup<T, K>>
-fun <T : ContractState, K : Any> groupStatesInternal(inGroups: Map<K, List<T>>, outGroups: Map<K, List<T>>): List<InOutGroup<T, K>>
fun hashCode(): Int
-val inStates: List<ContractState>
+val inputs: List<TransactionState<ContractState>>
val origHash: SecureHash
-val outStates: List<ContractState>
+val outputs: List<TransactionState<ContractState>>
+val signers: List<PublicKey>
+fun toTransactionForContract(): TransactionForContract
+val type: TransactionType
fun verify(): Unit
@@ -5240,7 +6345,7 @@ -TransactionGraphSearch(transactions: TransactionStorage, startPoints: List<WireTransaction>)
+TransactionGraphSearch(transactions: ReadOnlyTransactionStorage, startPoints: List<WireTransaction>)
class Query
@@ -5308,7 +6413,7 @@ Roots()
fun roots(body: Roots<T>.() -> Unit): Unit
-fun transaction(vararg outputStates: LabeledOutput): Unit
+fun transaction(vararg outputStates: LabeledOutput): Roots<T>
fun transaction(body: WireTransactionDSL<T>.() -> Unit): Unit
@@ -5328,11 +6433,11 @@ fun expectFailureOfTx(index: Int, message: String): Exception
-fun labelForState(state: T): String?
+fun labelForState(output: TransactionState<*>): String?
fun labelForTransaction(tx: WireTransaction): String?
fun labelForTransaction(tx: LedgerTransaction): String?
fun <C : ContractState> lookup(label: String): StateAndRef<C>
-val String.output: T
+val String.output: TransactionState<T>
val String.outputRef: StateRef
fun roots(body: Roots<T>.() -> Unit): <ERROR CLASS>
fun signAll(txnsToSign: List<WireTransaction> = txns, vararg extraKeys: KeyPair): List<SignedTransaction>
@@ -5357,7 +6462,22 @@ -interface TransactionStorage
+data class TransactionState<out T : ContractState>
+ +interface TransactionStorage : ReadOnlyTransactionStorage
+sealed class TransactionType
+ @@ -5391,6 +6580,18 @@ +class InvalidNotaryChange : TransactionVerificationException
+ class MoreThanOneNotary : TransactionVerificationException
    @@ -5403,6 +6604,18 @@
+class SignersMissing : TransactionVerificationException
+ val tx: TransactionForVerification
@@ -5436,10 +6649,13 @@ -Acceptor(otherSide: SingleMessageRecipient, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
+Acceptor(otherSide: Party, notary: Party, dealToBuy: T, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
protected open fun assembleSharedTX(handshake: Handshake<T>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>
val dealToBuy: T
+val notary: Party
+open val otherSide: Party
open val progressTracker: ProgressTracker
+open val sessionID: Long
protected open fun validateHandshake(handshake: Handshake<T>): Handshake<T>
@@ -5475,7 +6691,8 @@ -class Fixer<T : FixableDealState> : Secondary<StateRef>
+val FIX_INITIATE_TOPIC: String
+class Fixer : Secondary<StateRef>
-class Floater<T : FixableDealState> : Primary<StateRef>
+class FixingRoleDecider : ProtocolLogic<Unit>
+data class FixingSessionInitiation
+ +class Floater : Primary<StateRef>
+ @@ -5530,7 +6796,13 @@ -Instigator(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, dealBeingOffered: T, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
+Instigator(otherSide: Party, notary: Party, payload: T, myKeyPair: KeyPair, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
+open val myKeyPair: KeyPair
+val notary: Party
+open val notaryNode: NodeInfo
+open val otherSessionID: Long
+open val otherSide: Party
+open val payload: T
open val progressTracker: ProgressTracker
@@ -5543,7 +6815,7 @@ -Primary(payload: U, otherSide: SingleMessageRecipient, otherSessionID: Long, myKeyPair: KeyPair, notaryNode: NodeInfo, progressTracker: ProgressTracker = Primary.tracker())
+Primary(progressTracker: ProgressTracker = Primary.tracker())
object AWAITING_PROPOSAL : Step
object COPYING_TO_REGULATOR : Step
object NOTARY : Step
@@ -5553,11 +6825,11 @@ object VERIFYING : Step
open fun call(): SignedTransaction
fun getPartialTransaction(): UntrustworthyData<SignedTransaction>
-val myKeyPair: KeyPair
-val notaryNode: NodeInfo
-val otherSessionID: Long
-val otherSide: SingleMessageRecipient
-val payload: U
+abstract val myKeyPair: KeyPair
+abstract val notaryNode: NodeInfo
+abstract val otherSessionID: Long
+abstract val otherSide: Party
+abstract val payload: U
open val progressTracker: ProgressTracker
open fun signWithOurKey(partialTX: SignedTransaction): WithKey
fun tracker(): ProgressTracker
@@ -5573,7 +6845,7 @@ -Secondary(otherSide: SingleMessageRecipient, notary: Party, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
+Secondary(progressTracker: ProgressTracker = Secondary.tracker())
object RECEIVING : Step
object RECORDING : Step
object SIGNING : Step
@@ -5581,10 +6853,9 @@ object VERIFYING : Step
protected abstract fun assembleSharedTX(handshake: Handshake<U>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>
open fun call(): SignedTransaction
-val notary: Party
-val otherSide: SingleMessageRecipient
+abstract val otherSide: Party
open val progressTracker: ProgressTracker
-val sessionID: Long
+abstract val sessionID: Long
fun tracker(): ProgressTracker
protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U>
@@ -5638,15 +6909,15 @@ -Buyer(otherSide: SingleMessageRecipient, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>, sessionID: Long)
+Buyer(otherSide: Party, notary: Party, acceptablePrice: Amount<Issued<Currency>>, typeToBuy: Class<out OwnableState>, sessionID: Long)
object RECEIVING : Step
object SIGNING : Step
object SWAPPING_SIGNATURES : Step
object VERIFYING : Step
-val acceptablePrice: Amount<Currency>
+val acceptablePrice: Amount<Issued<Currency>>
open fun call(): SignedTransaction
val notary: Party
-val otherSide: SingleMessageRecipient
+val otherSide: Party
open val progressTracker: ProgressTracker
val sessionID: Long
val typeToBuy: Class<out OwnableState>
@@ -5661,7 +6932,7 @@ -Seller(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Currency>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())
+Seller(otherSide: Party, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())
object AWAITING_PROPOSAL : Step
object NOTARY : Step
object SENDING_SIGS : Step
@@ -5672,8 +6943,8 @@ open fun call(): SignedTransaction
val myKeyPair: KeyPair
val notaryNode: NodeInfo
-val otherSide: SingleMessageRecipient
-val price: Amount<Currency>
+val otherSide: Party
+val price: Amount<Issued<Currency>>
open val progressTracker: ProgressTracker
open fun signWithOurKey(partialTX: SignedTransaction): WithKey
fun tracker(): ProgressTracker
@@ -5688,9 +6959,9 @@ -SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Currency>, sellerOwnerKey: PublicKey, sessionID: Long)
+SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, sellerOwnerKey: PublicKey, sessionID: Long)
val assetForSale: StateAndRef<OwnableState>
-val price: Amount<Currency>
+val price: Amount<Issued<Currency>>
val sellerOwnerKey: PublicKey
val sessionID: Long
@@ -5719,14 +6990,26 @@ -UnacceptablePriceException(givenPrice: Amount<Currency>)
-val givenPrice: Amount<Currency>
+UnacceptablePriceException(givenPrice: Amount<Issued<Currency>>)
+val givenPrice: Amount<Issued<Currency>>
+interface TxWritableStorageService : StorageService
+ abstract class TypeOnlyCommandData : CommandData
    @@ -5790,7 +7073,7 @@
-abstract fun commit(tx: WireTransaction, callerIdentity: Party): Unit
+abstract fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit
@@ -5830,7 +7113,7 @@ -class Broadcast : ProtocolLogic<Boolean>
+class Broadcast : ProtocolLogic<Unit>
-class Updater : ProtocolLogic<Boolean>
- @@ -5921,8 +7167,8 @@ -ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
-fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
+ValidatingNotaryProtocol(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit
@@ -5934,14 +7180,14 @@ -ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
val logger: <ERROR CLASS>
val protocolFactory: Factory
-abstract class Wallet
+class Wallet
-object WalletFiller
- -class WalletImpl : Wallet
- interface WalletService
@@ -6038,7 +7257,7 @@ -WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<ContractState>, commands: List<Command>)
+WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<TransactionState<ContractState>>, commands: List<Command>, signers: List<PublicKey>, type: TransactionType)
val attachments: List<SecureHash>
val commands: List<Command>
fun deserialize(bits: SerializedBytes<WireTransaction>, kryo: <ERROR CLASS> = THREAD_LOCAL_KRYO.get()): WireTransaction
@@ -6046,9 +7265,11 @@ val inputs: List<StateRef>
fun <T : ContractState> outRef(index: Int): StateAndRef<T>
fun <T : ContractState> outRef(state: ContractState): StateAndRef<T>
-val outputs: List<ContractState>
+val outputs: List<TransactionState<ContractState>>
val serialized: SerializedBytes<WireTransaction>
+val signers: List<PublicKey>
fun toString(): String
+val type: TransactionType
@@ -6171,6 +7392,18 @@ +java.util.Currency
+ kotlin.ByteArray
    @@ -6328,7 +7561,7 @@
-kotlin.collections.Iterable
+kotlin.collections.Iterable
+kotlin.collections.Iterable
+ @@ -6452,15 +7700,15 @@ -State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party)
+State(issuance: PartyAndReference, owner: PublicKey, faceValue: Amount<Issued<Currency>>, maturityDate: Instant)
val contract: CommercialPaper
-val faceValue: Amount<Currency>
+val faceValue: Amount<Issued<Currency>>
val issuance: PartyAndReference
val maturityDate: Instant
-val notary: Party
val owner: PublicKey
+val participants: List<PublicKey>
fun toString(): String
-fun withFaceValue(newFaceValue: Amount<Currency>): <ERROR CLASS>
+fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): <ERROR CLASS>
fun withIssuance(newIssuance: PartyAndReference): <ERROR CLASS>
fun withMaturityDate(newMaturityDate: Instant): <ERROR CLASS>
fun withNewOwner(newOwner: PublicKey): <ERROR CLASS>
@@ -6469,11 +7717,11 @@ -fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Currency>, maturityDate: Instant, notary: Party): TransactionBuilder
+fun generateIssue(faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder
fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKey): Unit
-fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit
+fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<State>>): Unit
val legalContractReference: SecureHash
-fun verify(tx: TransactionForVerification): Unit
+fun verify(tx: TransactionForContract): Unit
@@ -6728,11 +7976,11 @@ -FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriod: DateOffset, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)
-fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: DateOffset = this.fixingPeriod, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg
+FloatingLeg(floatingRatePayer: Party, notional: Amount<Currency>, paymentFrequency: Frequency, effectiveDate: LocalDate, effectiveDateAdjustment: DateRollConvention?, terminationDate: LocalDate, terminationDateAdjustment: DateRollConvention?, dayCountBasisDay: DayCountBasisDay, dayCountBasisYear: DayCountBasisYear, dayInMonth: Int, paymentRule: PaymentRule, paymentDelay: Int, paymentCalendar: BusinessCalendar, interestPeriodAdjustment: AccrualAdjustment, rollConvention: DateRollConvention, fixingRollConvention: DateRollConvention, resetDayInMonth: Int, fixingPeriodOffset: Int, resetRule: PaymentRule, fixingsPerPayment: Frequency, fixingCalendar: BusinessCalendar, index: String, indexSource: String, indexTenor: Tenor)
+fun copy(floatingRatePayer: Party = this.floatingRatePayer, notional: Amount<Currency> = this.notional, paymentFrequency: Frequency = this.paymentFrequency, effectiveDate: LocalDate = this.effectiveDate, effectiveDateAdjustment: DateRollConvention? = this.effectiveDateAdjustment, terminationDate: LocalDate = this.terminationDate, terminationDateAdjustment: DateRollConvention? = this.terminationDateAdjustment, dayCountBasisDay: DayCountBasisDay = this.dayCountBasisDay, dayCountBasisYear: DayCountBasisYear = this.dayCountBasisYear, dayInMonth: Int = this.dayInMonth, paymentRule: PaymentRule = this.paymentRule, paymentDelay: Int = this.paymentDelay, paymentCalendar: BusinessCalendar = this.paymentCalendar, interestPeriodAdjustment: AccrualAdjustment = this.interestPeriodAdjustment, rollConvention: DateRollConvention = this.rollConvention, fixingRollConvention: DateRollConvention = this.fixingRollConvention, resetDayInMonth: Int = this.resetDayInMonth, fixingPeriod: Int = this.fixingPeriodOffset, resetRule: PaymentRule = this.resetRule, fixingsPerPayment: Frequency = this.fixingsPerPayment, fixingCalendar: BusinessCalendar = this.fixingCalendar, index: String = this.index, indexSource: String = this.indexSource, indexTenor: Tenor = this.indexTenor): FloatingLeg
open fun equals(other: Any?): Boolean
var fixingCalendar: BusinessCalendar
-var fixingPeriod: DateOffset
+var fixingPeriodOffset: Int
var fixingRollConvention: DateRollConvention
var fixingsPerPayment: Frequency
var floatingRatePayer: Party
@@ -6747,7 +7995,7 @@ -data class State : FixableDealState
+data class State : FixableDealState, SchedulableState
@@ -6930,7 +8179,7 @@ -package com.r3corda.contracts.cash
+package com.r3corda.contracts.asset
-interface State<T> : FungibleAssetState<T, AssetIssuanceDefinition<T>>
+class InsufficientBalanceException : Exception
-open fun verify(tx: TransactionForVerification): Unit
- - - -interface FungibleAssetState<T, I : AssetIssuanceDefinition<T>> : OwnableState
+val OBLIGATION_PROGRAM_ID: Obligation<Currency>
+class Obligation<P> : Contract
-class InsufficientBalanceException : Exception
+Obligation()
+data class BilateralNetState<P> : NetState<P>
-kotlin.collections.Iterable
+interface Commands : CommandData
+interface IssuanceCommands<P> : CommandData
+ +data class IssuanceDefinition<P>
+ +enum class Lifecycle
+ +data class MultilateralNetState<P> : NetState<P>
+ +interface NetState<P>
+ +data class State<P> : FungibleAssetState<P, IssuanceDefinition<P>>, BilateralNettableState<State<P>>
+ +data class StateTemplate<P>
+ +fun generateCloseOutNetting(tx: TransactionBuilder, signer: PublicKey, vararg states: State<P>): Unit
+fun generateIssue(tx: TransactionBuilder, obligor: Party, issuanceDef: StateTemplate<P>, pennies: Long, beneficiary: PublicKey, notary: Party): Unit
+fun generatePaymentNetting(tx: TransactionBuilder, issued: Issued<P>, notary: Party, vararg states: State<P>): Unit
+fun generateSetLifecycle(tx: TransactionBuilder, statesAndRefs: List<StateAndRef<State<P>>>, lifecycle: Lifecycle, notary: Party): Unit
+fun generateSettle(tx: TransactionBuilder, statesAndRefs: Iterable<StateAndRef<State<P>>>, assetStatesAndRefs: Iterable<StateAndRef<FungibleAssetState<P, *>>>, moveCommand: MoveCommand, notary: Party): Unit
+val legalContractReference: SecureHash
+fun verify(tx: TransactionForContract): Unit
+protected fun verifyIssueCommand(inputs: List<State<P>>, outputs: List<State<P>>, issueCommand: AuthenticatedObject<Issue<P>>, issued: Issued<P>, obligor: Party): Unit
+protected fun verifyNetCommand(inputs: Iterable<State<P>>, outputs: Iterable<State<P>>, command: AuthenticatedObject<Net>, netState: NetState<P>): Unit
+protected fun verifySetLifecycleCommand(inputs: List<State<P>>, outputs: List<State<P>>, tx: TransactionForContract, setLifecycleCommand: AuthenticatedObject<SetLifecycle<P>>): Unit
+ + + +val Wallet.cashBalances: Map<Currency, Amount<Currency>>
+fun <P> extractAmountsDue(product: P, states: Iterable<State<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>
+kotlin.collections.Iterable
+ +fun <P> netAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>
+fun <P> sumAmountsDue(balances: Map<<ERROR CLASS><PublicKey, PublicKey>, Amount<P>>): Map<PublicKey, Long>
@@ -7172,13 +8640,58 @@ -val Amount<Currency>.CASH: State
+val Amount<Currency>.CASH: State
+val DUMMY_CASH_ISSUER: PartyAndReference
+val DUMMY_CASH_ISSUER_KEY: <ERROR CLASS>
+object JavaTestHelpers
+ +val Amount<Issued<Currency>>.OBLIGATION: State<Currency>
+val Issued<Currency>.OBLIGATION_DEF: StateTemplate<Currency>
+val Amount<Issued<Currency>>.STATE: State
val TEST_PROGRAM_MAP: Map<Contract, Class<out Contract>>
-fun generateState(notary: Party = DUMMY_NOTARY): State
-infix fun State.issued by(party: Party): State
-infix fun State.owned by(owner: PublicKey): State
-infix fun State.owned by(owner: PublicKey): State
+infix fun <T> State<T>.at(dueBefore: Instant): State<T>
+infix fun <T> IssuanceDefinition<T>.at(dueBefore: Instant): IssuanceDefinition<T>
+infix fun <T> State<T>.between(parties: <ERROR CLASS><Party, PublicKey>): State<T>
+fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>, notary: Party = DUMMY_NOTARY, atLeastThisManyStates: Int = 3, atMostThisManyStates: Int = 10, rng: Random = Random(), ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 0 }))): Wallet
+fun generateState(): DummyState
+infix fun State.issued by(party: Party): State
+infix fun State.issued by(deposit: PartyAndReference): State
+infix fun <T> State<T>.issued by(party: Party): State<T>
+infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
+infix fun <T> State<T>.owned by(owner: PublicKey): <ERROR CLASS>
+infix fun State.owned by(owner: PublicKey): <ERROR CLASS>
infix fun <ERROR CLASS>.owned by(new_owner: PublicKey): <ERROR CLASS>
+infix fun State.with deposit(deposit: PartyAndReference): State
+infix fun State.with notary(notary: Party): TransactionState<State>
+infix fun State.with notary(notary: Party): TransactionState<State>
+infix fun ContractState.with notary(notary: Party): TransactionState<ContractState>
@@ -7211,9 +8724,10 @@ -ThreadBox(content: T, lock: Lock = ReentrantLock())
+ThreadBox(content: T, lock: ReentrantLock = ReentrantLock())
+inline fun <R> alreadyLocked(body: T.() -> R): R
val content: T
-val lock: Lock
+val lock: ReentrantLock
inline fun <R> locked(body: T.() -> R): R
@@ -7419,6 +8933,19 @@ +interface BilateralNettableState<T : BilateralNettableState<T>>
+ open class BusinessCalendar
@@ -7495,24 +9022,11 @@ abstract val contract: Contract
-abstract val notary: Party
+abstract val participants: List<PublicKey>
val DUMMY_PROGRAM_ID: DummyContract
-enum class DateOffset
- enum class DateRollConvention
- - - -class State : ContractState
+class Move : TypeOnlyCommandData, Commands
+ + + +data class MultiOwnerState : ContractState, State
+ +data class SingleOwnerState : OwnableState, State
+ +interface State : ContractState
+ fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder
val legalContractReference: SecureHash
-fun verify(tx: TransactionForVerification): Unit
+fun verify(tx: TransactionForContract): Unit
+ + + +data class DummyState : ContractState
+ @@ -7793,7 +9364,7 @@ -abstract fun generateFix(ptx: TransactionBuilder, oldStateRef: StateRef, fix: Fix): Unit
+abstract fun generateFix(ptx: TransactionBuilder, oldState: StateAndRef<*>, fix: Fix): Unit
abstract fun nextFixingOf(): FixOf?
@@ -7897,6 +9468,52 @@ val GBP: Currency
interface IssuanceDefinition
+interface IssueCommand : CommandData
+ +data class Issued<P>
+ +object JavaTestHelpers
+ data class LedgerTransaction : NamedByHash
@@ -7928,6 +9547,18 @@ +interface MoveCommand : CommandData
+ interface NamedByHash
    @@ -7940,6 +9571,19 @@
+enum class NetType
+ interface OwnableState : ContractState
    @@ -7995,6 +9639,58 @@
+interface SchedulableState : ContractState
+ +interface Scheduled
+ +data class ScheduledActivity : Scheduled
+ +data class ScheduledStateRef : Scheduled
+ data class SignedTransaction : NamedByHash
@@ -8024,9 +9722,9 @@ -StateAndRef(state: T, ref: StateRef)
+StateAndRef(state: TransactionState<T>, ref: StateRef)
val ref: StateRef
-val state: T
+val state: TransactionState<T>
@@ -8092,7 +9790,7 @@ -class TransactionBuilder
+abstract class TransactionBuilder
+data class TransactionForContract
+ data class TransactionForVerification
+data class TransactionState<out T : ContractState>
+ +sealed class TransactionType
+ sealed class TransactionVerificationException : Exception
    @@ -8256,6 +10074,18 @@
+class InvalidNotaryChange : TransactionVerificationException
+ class MoreThanOneNotary : TransactionVerificationException
    @@ -8268,6 +10098,18 @@
+class SignersMissing : TransactionVerificationException
+ val tx: TransactionForVerification
@@ -8295,7 +10137,7 @@ -WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<ContractState>, commands: List<Command>)
+WireTransaction(inputs: List<StateRef>, attachments: List<SecureHash>, outputs: List<TransactionState<ContractState>>, commands: List<Command>, signers: List<PublicKey>, type: TransactionType)
val attachments: List<SecureHash>
val commands: List<Command>
fun deserialize(bits: SerializedBytes<WireTransaction>, kryo: <ERROR CLASS> = THREAD_LOCAL_KRYO.get()): WireTransaction
@@ -8303,15 +10145,18 @@ val inputs: List<StateRef>
fun <T : ContractState> outRef(index: Int): StateAndRef<T>
fun <T : ContractState> outRef(state: ContractState): StateAndRef<T>
-val outputs: List<ContractState>
+val outputs: List<TransactionState<ContractState>>
val serialized: SerializedBytes<WireTransaction>
+val signers: List<PublicKey>
fun toString(): String
+val type: TransactionType
fun calculateDaysBetween(startDate: LocalDate, endDate: LocalDate, dcbYear: DayCountBasisYear, dcbDay: DayCountBasisDay): Int
fun currency(code: String): Currency
fun ContractState.hash(): SecureHash
+infix fun Amount<Currency>.issued by(deposit: PartyAndReference): Amount<Issued<Currency>>
java.time.LocalDate
    @@ -8324,6 +10169,18 @@
+java.util.Currency
+ kotlin.Double
    @@ -8383,7 +10240,8 @@
inline fun <R> requireThat(body: Requirements.() -> R): R
fun WireTransaction.toLedgerTransaction(identityService: IdentityService, attachmentStorage: AttachmentStorage): LedgerTransaction
-inline fun <reified T : CommandData> verifyMoveCommands(inputs: List<OwnableState>, tx: TransactionForVerification): Unit
+inline fun <reified T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, tx: TransactionForContract): Unit
+inline fun <reified T : CommandData> verifyMoveCommand(inputs: List<OwnableState>, commands: List<AuthenticatedObject<CommandData>>): Unit
fun SignedTransaction.verifyToLedgerTransaction(identityService: IdentityService, attachmentStorage: AttachmentStorage): LedgerTransaction
@@ -8538,7 +10396,7 @@ -fun generateKeyPair(): KeyPair
+fun generateKeyPair(): <ERROR CLASS>
java.security.KeyPair
    @@ -8594,6 +10452,7 @@
+fun newSecureRandom(): SecureRandom
fun OpaqueBytes.sha256(): SHA256
@@ -8695,6 +10554,7 @@ +object Ack : DeserializeAsKotlinObjectDef
interface AllPossibleRecipients : MessageRecipients
interface Message
+interface ReadOnlyTransactionStorage
+ +interface SchedulerService
+ abstract class ServiceType
@@ -9027,7 +10914,7 @@ -interface TransactionStorage
+interface TransactionStorage : ReadOnlyTransactionStorage
+interface TxWritableStorageService : StorageService
+ @@ -9089,11 +10987,11 @@ -abstract fun commit(tx: WireTransaction, callerIdentity: Party): Unit
+abstract fun commit(states: List<StateRef>, txId: SecureHash, callerIdentity: Party): Unit
-abstract class Wallet
+class Wallet
@@ -9201,7 +11098,7 @@ -class MockStorageService : SingletonSerializeAsToken, StorageService
+class MockStorageService : SingletonSerializeAsToken, TxWritableStorageService
@@ -9604,17 +11701,18 @@ TransactionForTest()
-fun accepts(time: Instant = TEST_TX_TIME): Unit
-fun chain(vararg outputLabels: String, body: TransactionForTest.() -> Unit): TransactionForTest
+fun accepts(time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure
+fun chain(vararg outputLabels: String, body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): TransactionForTest
open fun equals(other: Any?): Boolean
-infix fun fails requirement(msg: String): Unit
-fun fails_requirement(msg: String): Unit
+infix fun fails requirement(msg: String): LastLineShouldTestForAcceptOrFailure
+fun failsRequirement(msg: String): LastLineShouldTestForAcceptOrFailure
open fun hashCode(): Int
-fun input(s: () -> ContractState): <ERROR CLASS>
-fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): Unit
+fun input(s: () -> ContractState): Unit
+fun input(s: ContractState): Unit
+fun rejects(withMessage: String? = null, time: Instant = TEST_TX_TIME): LastLineShouldTestForAcceptOrFailure
protected fun runCommandsAndVerify(time: Instant): Unit
open fun toString(): String
-fun tweak(body: TransactionForTest.() -> Unit): TransactionForTest
+fun tweak(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure
@@ -9650,7 +11748,7 @@ Roots()
fun roots(body: Roots<T>.() -> Unit): Unit
-fun transaction(vararg outputStates: LabeledOutput): Unit
+fun transaction(vararg outputStates: LabeledOutput): Roots<T>
fun transaction(body: WireTransactionDSL<T>.() -> Unit): Unit
@@ -9670,11 +11768,11 @@ fun expectFailureOfTx(index: Int, message: String): Exception
-fun labelForState(state: T): String?
+fun labelForState(output: TransactionState<*>): String?
fun labelForTransaction(tx: WireTransaction): String?
fun labelForTransaction(tx: LedgerTransaction): String?
fun <C : ContractState> lookup(label: String): StateAndRef<C>
-val String.output: T
+val String.output: TransactionState<T>
val String.outputRef: StateRef
fun roots(body: Roots<T>.() -> Unit): <ERROR CLASS>
fun signAll(txnsToSign: List<WireTransaction> = txns, vararg extraKeys: KeyPair): List<SignedTransaction>
@@ -9688,9 +11786,9 @@ fun freeLocalHostAndPort(): <ERROR CLASS>
fun generateStateRef(): StateRef
-infix fun ContractState.label(label: String): LabeledOutput
+infix fun TransactionState<*>.label(label: String): LabeledOutput
inline fun <R> rootCauseExceptions(body: () -> R): R
-fun transaction(body: TransactionForTest.() -> Unit): <ERROR CLASS>
+fun transaction(body: TransactionForTest.() -> LastLineShouldTestForAcceptOrFailure): LastLineShouldTestForAcceptOrFailure
fun transactionGroup(body: TransactionGroupDSL<ContractState>.() -> Unit): <ERROR CLASS>
inline fun <reified T : ContractState> transactionGroupFor(body: TransactionGroupDSL<T>.() -> Unit): <ERROR CLASS>
@@ -9757,7 +11855,7 @@ -NonEmptySet(initial: T, set: MutableSet<T> = mutableSetOf())
+NonEmptySet(initial: T)
inner class Iterator<T, T> : MutableIterator<T>
    @@ -9791,6 +11889,19 @@
+object NonEmptySetSerializer
+ class ProgressTracker
    @@ -9970,6 +12081,21 @@
+data class TimeWindow
+ class UntrustworthyData<T>
    @@ -9986,6 +12112,7 @@
inline fun <reified T : Any> loggerFor(): <ERROR CLASS>
fun <T> nonEmptySetOf(initial: T, vararg elements: T): NonEmptySet<T>
+fun suggestInterestRateAnnouncementTimeWindow(index: String, source: String, date: LocalDate): TimeWindow
inline fun <ERROR CLASS>.trace(msg: () -> String): Unit
@@ -9998,8 +12125,109 @@ +sealed class CliParams
+ +object CliParamsSpec
+ +val DEFAULT_BASE_DIRECTORY: String
val DEMO_TOPIC: String
-val DIRNAME: String
class DemoClock : MutableClock, SerializeAsToken
    @@ -10017,6 +12245,20 @@
+enum class IRSDemoNode
+ enum class IRSDemoRole
    @@ -10047,63 +12289,11 @@
-class TraderDemoProtocolBuyer : ProtocolLogic<Unit>
- -class TraderDemoProtocolSeller : ProtocolLogic<Unit>
- fun main(args: Array<String>): Unit
fun main(args: Array<String>): Unit
fun main(args: Array<String>): Unit
-fun parseOptions(args: Array<String>, parser: <ERROR CLASS>): <ERROR CLASS>
-fun runBuyer(node: Node): Unit
-fun runSeller(myNetAddr: <ERROR CLASS>, node: Node, theirNetAddr: <ERROR CLASS>): Unit
-fun setupDirectory(mode: Role): Path
+fun runIRSDemo(args: Array<String>): Int
+fun runTraderDemo(args: Array<String>): Int
@@ -10161,10 +12351,11 @@ -AutoOfferMessage(otherSide: SingleMessageRecipient, otherSessionID: Long, dealBeingOffered: DealState)
+AutoOfferMessage(otherSide: Party, notary: Party, otherSessionID: Long, dealBeingOffered: DealState)
val dealBeingOffered: DealState
+val notary: Party
val otherSessionID: Long
-val otherSide: SingleMessageRecipient
+val otherSide: Party
@@ -10209,7 +12400,7 @@ -class Requester<T> : ProtocolLogic<SignedTransaction>
+class Requester : ProtocolLogic<SignedTransaction>
@@ -10579,7 +12734,7 @@ fun buildTransaction(type: ContractDefRef, steps: List<TransactionBuildStep>): SerializedBytes<WireTransaction>
fun commitTransaction(tx: SerializedBytes<WireTransaction>, signatures: List<WithKey>): SecureHash
fun fetchProtocolsRequiringAttention(query: StatesQuery): Map<StateRef, ProtocolRequiringAttention>
-fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
+fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?>
fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?>
fun generateTransactionSignature(tx: SerializedBytes<WireTransaction>): WithKey
fun invokeProtocolSync(type: ProtocolRef, args: Map<String, Any?>): Any?
@@ -10587,6 +12742,7 @@ fun provideProtocolResponse(protocol: ProtocolInstanceRef, choice: SecureHash, args: Map<String, Any?>): Unit
fun queryStates(query: StatesQuery): List<StateRef>
fun serverTime(): LocalDateTime
+fun status(): <ERROR CLASS>
@@ -10607,14 +12763,15 @@ lateinit var checkpointStorage: CheckpointStorage
val configuration: NodeConfiguration
protected open fun constructStorageService(attachments: NodeAttachmentService, transactionStorage: TransactionStorage, keypair: KeyPair, identity: Party): StorageServiceImpl
+protected fun createNodeDir(): Unit
val dir: Path
open fun findMyLocation(): PhysicalLocation?
-protected open fun generateKeyPair(): KeyPair
+protected open fun generateKeyPair(): <ERROR CLASS>
lateinit var identity: IdentityService
var inNodeNetworkMapService: NetworkMapService?
var inNodeNotaryService: NotaryService?
val info: NodeInfo
-protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><StorageService, CheckpointStorage>
+protected open fun initialiseStorageService(dir: Path): <ERROR CLASS><TxWritableStorageService, CheckpointStorage>
lateinit var interestRatesService: Service
var isPreviousCheckpointsPresent: Boolean
lateinit var keyManagement: E2ETestKeyManagementService
@@ -10631,15 +12788,17 @@ val networkMapService: NodeInfo?
protected open fun noNetworkMapConfigured(): <ERROR CLASS><Unit>
val platformClock: Clock
+lateinit var scheduler: SchedulerService
protected abstract val serverThread: AffinityExecutor
val services: ServiceHubInternal
val servicesThatAcceptUploads: List<AcceptsFileUpload>
+open fun setup(): AbstractNode
lateinit var smm: StateMachineManager
open fun start(): AbstractNode
protected abstract fun startMessagingService(): Unit
var started: Boolean
open fun stop(): Unit
-lateinit var storage: StorageService
+lateinit var storage: TxWritableStorageService
lateinit var wallet: WalletService
@@ -10664,17 +12823,19 @@ -Node(dir: Path, p2pAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())
+Node(dir: Path, p2pAddr: <ERROR CLASS>, webServerAddr: <ERROR CLASS>, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set<ServiceType>, clock: Clock = NodeClock(), clientAPIs: List<Class<*>> = listOf())
val DEFAULT_PORT: Int
val clientAPIs: List<Class<*>>
protected val log: <ERROR CLASS>
protected fun makeMessagingService(): MessagingService
val p2pAddr: <ERROR CLASS>
protected val serverThread: ServiceAffinityExecutor
+fun setup(): Node
fun start(): Node
protected fun startMessagingService(): Unit
fun stop(): Unit
lateinit var webServer: <ERROR CLASS>
+val webServerAddr: <ERROR CLASS>
@@ -10697,7 +12858,7 @@ -IRSSimulation(runAsync: Boolean, latencyInjector: LatencyCalculator?)
+IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, latencyInjector: LatencyCalculator?)
fun iterate(): MessageTransfer?
val om: <ERROR CLASS>
protected fun startMainSimulation(): <ERROR CLASS><Unit>
@@ -10712,7 +12873,7 @@ -MockNetwork(threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)
+MockNetwork(networkSendManuallyPumped: Boolean = false, threadPerNode: Boolean = false, defaultFactory: Factory = MockNetwork.DefaultFactory)
object DefaultFactory : Factory
-object WalletFiller
+fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*>
+fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<MultiOwnerState>
+fun issueState(node: AbstractNode): StateAndRef<*>
+kotlin.collections.Iterable
-fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef
-fun issueState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef
@@ -10962,6 +13128,42 @@ +package com.r3corda.node.services
+ package com.r3corda.node.services.api
-interface ServiceHubInternal : ServiceHub
+abstract class ServiceHubInternal : ServiceHub
@@ -11127,10 +13333,11 @@ -Oracle(identity: Party, signingKey: KeyPair)
+Oracle(identity: Party, signingKey: KeyPair, clock: Clock)
+val clock: Clock
val identity: Party
var knownFixes: FixContainer
-fun query(queries: List<FixOf>): List<Fix>
+fun query(queries: List<FixOf>, deadline: Instant): List<Fix>
fun sign(wtx: WireTransaction): LegallyIdentifiable
@@ -11153,7 +13360,7 @@ object Type : ServiceType
-class UnknownFix : Exception
+class UnknownFix : RetryableException
@@ -11218,6 +13424,44 @@ +package com.r3corda.node.services.events
+ package com.r3corda.node.services.identity
val REGISTER_PROTOCOL_TOPIC: String
-class RegistrationRequest : AbstractRequestMessage
+class RegistrationRequest : NetworkMapRequestMessage
val SUBSCRIPTION_PROTOCOL_TOPIC: String
-class SubscribeRequest : AbstractRequestMessage
+class SubscribeRequest : NetworkMapRequestMessage
-open class StorageServiceImpl : SingletonSerializeAsToken, StorageService
+open class StorageServiceImpl : SingletonSerializeAsToken, TxWritableStorageService
@@ -12032,7 +14297,7 @@ -NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+NotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
abstract val logger: <ERROR CLASS>
abstract val protocolFactory: Factory
@@ -12050,7 +14315,7 @@ -SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+SimpleNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
val logger: <ERROR CLASS>
val protocolFactory: DefaultFactory
@@ -12065,7 +14330,7 @@ -ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+ValidatingNotaryService(smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider, networkMapCache: NetworkMapCache)
object Type : ServiceType
val logger: <ERROR CLASS>
val protocolFactory: Factory
@@ -12096,7 +14361,7 @@ -class NodeWalletService : SingletonSerializeAsToken, WalletService
+class NodeWalletService : InMemoryWalletService
-class WalletImpl : Wallet
- @@ -12372,6 +14618,30 @@ +object PublicKeyDeserializer
+ +object PublicKeySerializer
+ class SecureHashDeserializer<T : SecureHash>
+class SignaturesMissing : NotaryError
+ class TimestampInvalid : NotaryError
@@ -12729,7 +15013,7 @@ -abstract fun create(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
+abstract fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider): Service
@@ -12741,8 +15025,9 @@ -Handshake(replyTo: SingleMessageRecipient, sendSessionID: Long, sessionID: Long)
+Handshake(replyTo: Party, sendSessionID: Long, sessionID: Long)
val sendSessionID: Long
+val sessionID: Long
@@ -12769,10 +15054,10 @@ -Service(otherSide: SingleMessageRecipient, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
-open fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
+Service(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+open fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit
open fun call(): Unit
-val otherSide: SingleMessageRecipient
+val otherSide: Party
val receiveSessionID: Long
val sendSessionID: Long
val timestampChecker: TimestampChecker
@@ -12788,9 +15073,9 @@ -SignRequest(txBits: SerializedBytes<WireTransaction>, callerIdentity: Party)
+SignRequest(tx: SignedTransaction, callerIdentity: Party)
val callerIdentity: Party
-val txBits: SerializedBytes<WireTransaction>
+val tx: SignedTransaction
@@ -12807,7 +15092,7 @@ -RatesFixProtocol(tx: TransactionBuilder, oracle: NodeInfo, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))
+RatesFixProtocol(tx: TransactionBuilder, oracle: Party, fixOf: FixOf, expectedRate: BigDecimal, rateTolerance: BigDecimal, timeOut: Duration, progressTracker: ProgressTracker = RatesFixProtocol.tracker(fixOf.name))
class FixOutOfRange : Exception
@@ -12856,7 +15143,8 @@ -SignRequest(tx: WireTransaction, replyTo: SingleMessageRecipient, sessionID: Long)
+SignRequest(tx: WireTransaction, replyTo: Party, sessionID: Long)
+val sessionID: Long
val tx: WireTransaction
@@ -12883,9 +15171,9 @@ -ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: SingleMessageRecipient)
-ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: SingleMessageRecipient)
-ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: SingleMessageRecipient)
+ResolveTransactionsProtocol(stx: SignedTransaction, otherSide: Party)
+ResolveTransactionsProtocol(wtx: WireTransaction, otherSide: Party)
+ResolveTransactionsProtocol(txHashes: Set<SecureHash>, otherSide: Party)
class ExcessivelyLargeTransactionGraph : Exception
    @@ -12902,6 +15190,19 @@
+interface ServiceRequestMessage
+ object TwoPartyDealProtocol
-class Fixer<T : FixableDealState> : Secondary<StateRef>
+val FIX_INITIATE_TOPIC: String
+class Fixer : Secondary<StateRef>
-class Floater<T : FixableDealState> : Primary<StateRef>
+class FixingRoleDecider : ProtocolLogic<Unit>
+data class FixingSessionInitiation
+ +class Floater : Primary<StateRef>
+ @@ -13012,7 +15366,13 @@ -Instigator(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, dealBeingOffered: T, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
+Instigator(otherSide: Party, notary: Party, payload: T, myKeyPair: KeyPair, otherSessionID: Long, progressTracker: ProgressTracker = Primary.tracker())
+open val myKeyPair: KeyPair
+val notary: Party
+open val notaryNode: NodeInfo
+open val otherSessionID: Long
+open val otherSide: Party
+open val payload: T
open val progressTracker: ProgressTracker
@@ -13025,7 +15385,7 @@ -Primary(payload: U, otherSide: SingleMessageRecipient, otherSessionID: Long, myKeyPair: KeyPair, notaryNode: NodeInfo, progressTracker: ProgressTracker = Primary.tracker())
+Primary(progressTracker: ProgressTracker = Primary.tracker())
object AWAITING_PROPOSAL : Step
object COPYING_TO_REGULATOR : Step
object NOTARY : Step
@@ -13035,11 +15395,11 @@ object VERIFYING : Step
open fun call(): SignedTransaction
fun getPartialTransaction(): UntrustworthyData<SignedTransaction>
-val myKeyPair: KeyPair
-val notaryNode: NodeInfo
-val otherSessionID: Long
-val otherSide: SingleMessageRecipient
-val payload: U
+abstract val myKeyPair: KeyPair
+abstract val notaryNode: NodeInfo
+abstract val otherSessionID: Long
+abstract val otherSide: Party
+abstract val payload: U
open val progressTracker: ProgressTracker
open fun signWithOurKey(partialTX: SignedTransaction): WithKey
fun tracker(): ProgressTracker
@@ -13055,7 +15415,7 @@ -Secondary(otherSide: SingleMessageRecipient, notary: Party, sessionID: Long, progressTracker: ProgressTracker = Secondary.tracker())
+Secondary(progressTracker: ProgressTracker = Secondary.tracker())
object RECEIVING : Step
object RECORDING : Step
object SIGNING : Step
@@ -13063,10 +15423,9 @@ object VERIFYING : Step
protected abstract fun assembleSharedTX(handshake: Handshake<U>): <ERROR CLASS><TransactionBuilder, List<PublicKey>>
open fun call(): SignedTransaction
-val notary: Party
-val otherSide: SingleMessageRecipient
+abstract val otherSide: Party
open val progressTracker: ProgressTracker
-val sessionID: Long
+abstract val sessionID: Long
fun tracker(): ProgressTracker
protected abstract fun validateHandshake(handshake: Handshake<U>): Handshake<U>
@@ -13120,15 +15479,15 @@ -Buyer(otherSide: SingleMessageRecipient, notary: Party, acceptablePrice: Amount<Currency>, typeToBuy: Class<out OwnableState>, sessionID: Long)
+Buyer(otherSide: Party, notary: Party, acceptablePrice: Amount<Issued<Currency>>, typeToBuy: Class<out OwnableState>, sessionID: Long)
object RECEIVING : Step
object SIGNING : Step
object SWAPPING_SIGNATURES : Step
object VERIFYING : Step
-val acceptablePrice: Amount<Currency>
+val acceptablePrice: Amount<Issued<Currency>>
open fun call(): SignedTransaction
val notary: Party
-val otherSide: SingleMessageRecipient
+val otherSide: Party
open val progressTracker: ProgressTracker
val sessionID: Long
val typeToBuy: Class<out OwnableState>
@@ -13143,7 +15502,7 @@ -Seller(otherSide: SingleMessageRecipient, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Currency>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())
+Seller(otherSide: Party, notaryNode: NodeInfo, assetToSell: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, myKeyPair: KeyPair, buyerSessionID: Long, progressTracker: ProgressTracker = Seller.tracker())
object AWAITING_PROPOSAL : Step
object NOTARY : Step
object SENDING_SIGS : Step
@@ -13154,8 +15513,8 @@ open fun call(): SignedTransaction
val myKeyPair: KeyPair
val notaryNode: NodeInfo
-val otherSide: SingleMessageRecipient
-val price: Amount<Currency>
+val otherSide: Party
+val price: Amount<Issued<Currency>>
open val progressTracker: ProgressTracker
open fun signWithOurKey(partialTX: SignedTransaction): WithKey
fun tracker(): ProgressTracker
@@ -13170,9 +15529,9 @@ -SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Currency>, sellerOwnerKey: PublicKey, sessionID: Long)
+SellerTradeInfo(assetForSale: StateAndRef<OwnableState>, price: Amount<Issued<Currency>>, sellerOwnerKey: PublicKey, sessionID: Long)
val assetForSale: StateAndRef<OwnableState>
-val price: Amount<Currency>
+val price: Amount<Issued<Currency>>
val sellerOwnerKey: PublicKey
val sessionID: Long
@@ -13201,8 +15560,8 @@ -UnacceptablePriceException(givenPrice: Amount<Currency>)
-val givenPrice: Amount<Currency>
+UnacceptablePriceException(givenPrice: Amount<Issued<Currency>>)
+val givenPrice: Amount<Issued<Currency>>
@@ -13217,8 +15576,204 @@ -ValidatingNotaryProtocol(otherSide: SingleMessageRecipient, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
-fun beforeCommit(wtx: WireTransaction, reqIdentity: Party): Unit
+ValidatingNotaryProtocol(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, timestampChecker: TimestampChecker, uniquenessProvider: UniquenessProvider)
+fun beforeCommit(stx: SignedTransaction, reqIdentity: Party): Unit
+ + + + + + +package protocols
+
    + + +Module Contents + + + +abstract class AbstractStateReplacementProtocol<T>
    + +object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>
    + +class StateReplacementException : Exception
    + +class StateReplacementRefused
    + diff --git a/docs/build/html/api/index.html b/docs/build/html/api/index.html index 89d4c0fbf7..0718d4e57a 100644 --- a/docs/build/html/api/index.html +++ b/docs/build/html/api/index.html @@ -17,7 +17,7 @@ -com.r3corda.contracts.cash +com.r3corda.contracts.asset @@ -143,6 +143,12 @@ +com.r3corda.node.services + + + + + com.r3corda.node.services.api @@ -161,6 +167,12 @@ +com.r3corda.node.services.events + + + + + com.r3corda.node.services.identity @@ -225,6 +237,12 @@ + + +protocols + + +

    Index

    diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-a-p-p-r-o-v-i-n-g.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-a-p-p-r-o-v-i-n-g.html new file mode 100644 index 0000000000..8ad48ddddf --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-a-p-p-r-o-v-i-n-g.html @@ -0,0 +1,42 @@ + + +AbstractStateReplacementProtocol.Acceptor.APPROVING - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / APPROVING
    +
    +

    APPROVING

    +object APPROVING : Step
    +
    +
    +

    Inherited Properties

    + + + + + + + + + + + +
    +changes +open val changes: <ERROR CLASS><Change>
    +label +open val label: String
    +

    Inherited Functions

    + + + + + + + +
    +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-init-.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-init-.html new file mode 100644 index 0000000000..c31c8dce5b --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-init-.html @@ -0,0 +1,14 @@ + + +AbstractStateReplacementProtocol.Acceptor.<init> - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / <init>
    +
    +

    <init>

    +Acceptor(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, progressTracker: ProgressTracker = tracker())
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-r-e-j-e-c-t-i-n-g.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-r-e-j-e-c-t-i-n-g.html new file mode 100644 index 0000000000..dbe5439a2e --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-r-e-j-e-c-t-i-n-g.html @@ -0,0 +1,42 @@ + + +AbstractStateReplacementProtocol.Acceptor.REJECTING - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / REJECTING
    +
    +

    REJECTING

    +object REJECTING : Step
    +
    +
    +

    Inherited Properties

    + + + + + + + + + + + +
    +changes +open val changes: <ERROR CLASS><Change>
    +label +open val label: String
    +

    Inherited Functions

    + + + + + + + +
    +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html new file mode 100644 index 0000000000..9291d36264 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.TOPIC_CHANGE - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / TOPIC_CHANGE
    +
    +

    TOPIC_CHANGE

    + +abstract val TOPIC_CHANGE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html new file mode 100644 index 0000000000..2ee61da22f --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.TOPIC_INITIATE - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / TOPIC_INITIATE
    +
    +

    TOPIC_INITIATE

    + +abstract val TOPIC_INITIATE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-v-e-r-i-f-y-i-n-g.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-v-e-r-i-f-y-i-n-g.html new file mode 100644 index 0000000000..1449acfb2a --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/-v-e-r-i-f-y-i-n-g.html @@ -0,0 +1,42 @@ + + +AbstractStateReplacementProtocol.Acceptor.VERIFYING - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / VERIFYING
    +
    +

    VERIFYING

    +object VERIFYING : Step
    +
    +
    +

    Inherited Properties

    + + + + + + + + + + + +
    +changes +open val changes: <ERROR CLASS><Change>
    +label +open val label: String
    +

    Inherited Functions

    + + + + + + + +
    +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/call.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/call.html new file mode 100644 index 0000000000..a3d1d47f1d --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/call.html @@ -0,0 +1,17 @@ + + +AbstractStateReplacementProtocol.Acceptor.call - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / call
    +
    +

    call

    + +open fun call(): Unit
    +Overrides ProtocolLogic.call
    +

    This is where you fill out your business logic.

    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/index.html new file mode 100644 index 0000000000..a95fea183c --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/index.html @@ -0,0 +1,187 @@ + + +AbstractStateReplacementProtocol.Acceptor - + + + +protocols / AbstractStateReplacementProtocol / Acceptor
    +
    +

    Acceptor

    +abstract class Acceptor<T> : ProtocolLogic<Unit>
    +
    +
    +

    Types

    + + + + + + + + + + + + + + + +
    +APPROVING +object APPROVING : Step
    +REJECTING +object REJECTING : Step
    +VERIFYING +object VERIFYING : Step
    +

    Constructors

    + + + + + + + +
    +<init> +Acceptor(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, progressTracker: ProgressTracker = tracker())
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +TOPIC_CHANGE +abstract val TOPIC_CHANGE: String
    +TOPIC_INITIATE +abstract val TOPIC_INITIATE: String
    +otherSide +val otherSide: Party
    +progressTracker +open val progressTracker: ProgressTracker

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +
    +sessionIdForReceive +val sessionIdForReceive: Long
    +sessionIdForSend +val sessionIdForSend: Long
    +

    Inherited Properties

    + + + + + + + + + + + + + + + +
    +logger +val logger: <ERROR CLASS>

    This is where you should log things to.

    +
    +psm +lateinit var psm: ProtocolStateMachine<*>

    Reference to the Fiber instance that is the top level controller for the entire flow.

    +
    +serviceHub +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    +
    +

    Functions

    + + + + + + + +
    +call +open fun call(): Unit

    This is where you fill out your business logic.

    +
    +

    Inherited Functions

    + + + + + + + + + + + + + + + + + + + +
    +receive +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
    +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
    +send +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
    +sendAndReceive +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T>
    +subProtocol +fun <R> subProtocol(subLogic: ProtocolLogic<R>): R

    Invokes the given subprotocol by simply passing through this ProtocolLogics reference to the +ProtocolStateMachine and then calling the call method.

    +
    +

    Companion Object Functions

    + + + + + + + +
    +tracker +fun tracker(): ProgressTracker
    +

    Inheritors

    + + + + + + + +
    +Acceptor +class Acceptor : Acceptor<Party>
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/other-side.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/other-side.html new file mode 100644 index 0000000000..df32738e21 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/other-side.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.otherSide - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / otherSide
    +
    +

    otherSide

    + +val otherSide: Party
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/progress-tracker.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/progress-tracker.html new file mode 100644 index 0000000000..03ebffb4a1 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/progress-tracker.html @@ -0,0 +1,24 @@ + + +AbstractStateReplacementProtocol.Acceptor.progressTracker - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / progressTracker
    +
    +

    progressTracker

    + +open val progressTracker: ProgressTracker
    +Overrides ProtocolLogic.progressTracker
    +

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +

    Note that this has to return a tracker before the protocol is invoked. You cant change your mind half way +through.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-receive.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-receive.html new file mode 100644 index 0000000000..d226ee0006 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-receive.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.sessionIdForReceive - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / sessionIdForReceive
    +
    +

    sessionIdForReceive

    + +val sessionIdForReceive: Long
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-send.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-send.html new file mode 100644 index 0000000000..e0acb9df94 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/session-id-for-send.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.sessionIdForSend - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / sessionIdForSend
    +
    +

    sessionIdForSend

    + +val sessionIdForSend: Long
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/tracker.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/tracker.html new file mode 100644 index 0000000000..6f7226bd5d --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-acceptor/tracker.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Acceptor.tracker - + + + +protocols / AbstractStateReplacementProtocol / Acceptor / tracker
    +
    +

    tracker

    + +fun tracker(): ProgressTracker
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/-init-.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/-init-.html new file mode 100644 index 0000000000..8e0a0e34a9 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/-init-.html @@ -0,0 +1,14 @@ + + +AbstractStateReplacementProtocol.Handshake.<init> - + + + +protocols / AbstractStateReplacementProtocol / Handshake / <init>
    +
    +

    <init>

    +Handshake(sessionIdForSend: Long, replyTo: Party, sessionID: Long)
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/index.html new file mode 100644 index 0000000000..ff3bd5511f --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/index.html @@ -0,0 +1,64 @@ + + +AbstractStateReplacementProtocol.Handshake - + + + +protocols / AbstractStateReplacementProtocol / Handshake
    +
    +

    Handshake

    +class Handshake : AbstractRequestMessage
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +Handshake(sessionIdForSend: Long, replyTo: Party, sessionID: Long)
    +

    Properties

    + + + + + + + + + + + +
    +sessionID +val sessionID: Long
    +sessionIdForSend +val sessionIdForSend: Long
    +

    Inherited Properties

    + + + + + + + +
    +replyToParty +val replyToParty: Party
    +

    Inherited Functions

    + + + + + + + +
    +getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-i-d.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-i-d.html new file mode 100644 index 0000000000..5562ba3381 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-i-d.html @@ -0,0 +1,16 @@ + + +AbstractStateReplacementProtocol.Handshake.sessionID - + + + +protocols / AbstractStateReplacementProtocol / Handshake / sessionID
    +
    +

    sessionID

    + +val sessionID: Long
    +Overrides ServiceRequestMessage.sessionID
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-id-for-send.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-id-for-send.html new file mode 100644 index 0000000000..00903d6f7f --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-handshake/session-id-for-send.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Handshake.sessionIdForSend - + + + +protocols / AbstractStateReplacementProtocol / Handshake / sessionIdForSend
    +
    +

    sessionIdForSend

    + +val sessionIdForSend: Long
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-init-.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-init-.html new file mode 100644 index 0000000000..3c1d4ac94d --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-init-.html @@ -0,0 +1,23 @@ + + +AbstractStateReplacementProtocol.<init> - + + + +protocols / AbstractStateReplacementProtocol / <init>
    +
    +

    <init>

    +AbstractStateReplacementProtocol()
    +

    Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. +Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these +protocols.

    +

    The Instigator assembles the transaction for state replacement and sends out change proposals to all participants +(Acceptor) of that state. If participants agree to the proposed change, they each sign the transaction. +Finally, Instigator sends the transaction containing all signatures back to each participant so they can record it and +use the new updated state for future transactions.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-init-.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-init-.html new file mode 100644 index 0000000000..4e44255124 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-init-.html @@ -0,0 +1,14 @@ + + +AbstractStateReplacementProtocol.Instigator.<init> - + + + +protocols / AbstractStateReplacementProtocol / Instigator / <init>
    +
    +

    <init>

    +Instigator(originalState: StateAndRef<S>, modification: T, progressTracker: ProgressTracker = tracker())
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-n-o-t-a-r-y.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-n-o-t-a-r-y.html new file mode 100644 index 0000000000..156fb15244 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-n-o-t-a-r-y.html @@ -0,0 +1,42 @@ + + +AbstractStateReplacementProtocol.Instigator.NOTARY - + + + +protocols / AbstractStateReplacementProtocol / Instigator / NOTARY
    +
    +

    NOTARY

    +object NOTARY : Step
    +
    +
    +

    Inherited Properties

    + + + + + + + + + + + +
    +changes +open val changes: <ERROR CLASS><Change>
    +label +open val label: String
    +

    Inherited Functions

    + + + + + + + +
    +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-s-i-g-n-i-n-g.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-s-i-g-n-i-n-g.html new file mode 100644 index 0000000000..03ef9a7d34 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-s-i-g-n-i-n-g.html @@ -0,0 +1,42 @@ + + +AbstractStateReplacementProtocol.Instigator.SIGNING - + + + +protocols / AbstractStateReplacementProtocol / Instigator / SIGNING
    +
    +

    SIGNING

    +object SIGNING : Step
    +
    +
    +

    Inherited Properties

    + + + + + + + + + + + +
    +changes +open val changes: <ERROR CLASS><Change>
    +label +open val label: String
    +

    Inherited Functions

    + + + + + + + +
    +childProgressTracker +open fun childProgressTracker(): ProgressTracker?
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html new file mode 100644 index 0000000000..c36e7d3f97 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Instigator.TOPIC_CHANGE - + + + +protocols / AbstractStateReplacementProtocol / Instigator / TOPIC_CHANGE
    +
    +

    TOPIC_CHANGE

    + +abstract val TOPIC_CHANGE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html new file mode 100644 index 0000000000..7466a341a8 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Instigator.TOPIC_INITIATE - + + + +protocols / AbstractStateReplacementProtocol / Instigator / TOPIC_INITIATE
    +
    +

    TOPIC_INITIATE

    + +abstract val TOPIC_INITIATE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/call.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/call.html new file mode 100644 index 0000000000..1a592d2eff --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/call.html @@ -0,0 +1,17 @@ + + +AbstractStateReplacementProtocol.Instigator.call - + + + +protocols / AbstractStateReplacementProtocol / Instigator / call
    +
    +

    call

    + +open fun call(): StateAndRef<S>
    +Overrides ProtocolLogic.call
    +

    This is where you fill out your business logic.

    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/index.html new file mode 100644 index 0000000000..a06b1246d5 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/index.html @@ -0,0 +1,175 @@ + + +AbstractStateReplacementProtocol.Instigator - + + + +protocols / AbstractStateReplacementProtocol / Instigator
    +
    +

    Instigator

    +abstract class Instigator<S : ContractState, T> : ProtocolLogic<StateAndRef<S>>
    +
    +
    +

    Types

    + + + + + + + + + + + +
    +NOTARY +object NOTARY : Step
    +SIGNING +object SIGNING : Step
    +

    Constructors

    + + + + + + + +
    +<init> +Instigator(originalState: StateAndRef<S>, modification: T, progressTracker: ProgressTracker = tracker())
    +

    Properties

    + + + + + + + + + + + + + + + + + + + + + + + +
    +TOPIC_CHANGE +abstract val TOPIC_CHANGE: String
    +TOPIC_INITIATE +abstract val TOPIC_INITIATE: String
    +modification +val modification: T
    +originalState +val originalState: StateAndRef<S>
    +progressTracker +open val progressTracker: ProgressTracker

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +
    +

    Inherited Properties

    + + + + + + + + + + + + + + + +
    +logger +val logger: <ERROR CLASS>

    This is where you should log things to.

    +
    +psm +lateinit var psm: ProtocolStateMachine<*>

    Reference to the Fiber instance that is the top level controller for the entire flow.

    +
    +serviceHub +val serviceHub: ServiceHub

    Provides access to big, heavy classes that may be reconstructed from time to time, e.g. across restarts. It is +only available once the protocol has started, which means it cannnot be accessed in the constructor. Either +access this lazily or from inside call.

    +
    +

    Functions

    + + + + + + + +
    +call +open fun call(): StateAndRef<S>

    This is where you fill out your business logic.

    +
    +

    Inherited Functions

    + + + + + + + + + + + + + + + + + + + +
    +receive +fun <T : Any> receive(topic: String, sessionIDForReceive: Long): UntrustworthyData<T>
    +fun <T : Any> receive(topic: String, sessionIDForReceive: Long, clazz: Class<T>): UntrustworthyData<T>
    +send +fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
    +sendAndReceive +fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any): UntrustworthyData<T>
    +subProtocol +fun <R> subProtocol(subLogic: ProtocolLogic<R>): R

    Invokes the given subprotocol by simply passing through this ProtocolLogics reference to the +ProtocolStateMachine and then calling the call method.

    +
    +

    Companion Object Functions

    + + + + + + + +
    +tracker +fun tracker(): ProgressTracker
    +

    Inheritors

    + + + + + + + +
    +Instigator +class Instigator<T : ContractState> : Instigator<T, Party>
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/modification.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/modification.html new file mode 100644 index 0000000000..43a88f397c --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/modification.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Instigator.modification - + + + +protocols / AbstractStateReplacementProtocol / Instigator / modification
    +
    +

    modification

    + +val modification: T
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/original-state.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/original-state.html new file mode 100644 index 0000000000..1fdc2258a1 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/original-state.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Instigator.originalState - + + + +protocols / AbstractStateReplacementProtocol / Instigator / originalState
    +
    +

    originalState

    + +val originalState: StateAndRef<S>
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/progress-tracker.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/progress-tracker.html new file mode 100644 index 0000000000..ebf7ba287d --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/progress-tracker.html @@ -0,0 +1,24 @@ + + +AbstractStateReplacementProtocol.Instigator.progressTracker - + + + +protocols / AbstractStateReplacementProtocol / Instigator / progressTracker
    +
    +

    progressTracker

    + +open val progressTracker: ProgressTracker
    +Overrides ProtocolLogic.progressTracker
    +

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +

    Note that this has to return a tracker before the protocol is invoked. You cant change your mind half way +through.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/tracker.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/tracker.html new file mode 100644 index 0000000000..df3e81ee67 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-instigator/tracker.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Instigator.tracker - + + + +protocols / AbstractStateReplacementProtocol / Instigator / tracker
    +
    +

    tracker

    + +fun tracker(): ProgressTracker
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/index.html new file mode 100644 index 0000000000..21b3a0f1bc --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/index.html @@ -0,0 +1,48 @@ + + +AbstractStateReplacementProtocol.Proposal - + + + +protocols / AbstractStateReplacementProtocol / Proposal
    +
    +

    Proposal

    +interface Proposal<T>
    +
    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +modification +abstract val modification: T
    +stateRef +abstract val stateRef: StateRef
    +stx +abstract val stx: SignedTransaction
    +

    Inheritors

    + + + + + + + +
    +Proposal +data class Proposal : Proposal<Party>
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/modification.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/modification.html new file mode 100644 index 0000000000..cd6b3b51eb --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/modification.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Proposal.modification - + + + +protocols / AbstractStateReplacementProtocol / Proposal / modification
    +
    +

    modification

    + +abstract val modification: T
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/state-ref.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/state-ref.html new file mode 100644 index 0000000000..06d89d95b5 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/state-ref.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Proposal.stateRef - + + + +protocols / AbstractStateReplacementProtocol / Proposal / stateRef
    +
    +

    stateRef

    + +abstract val stateRef: StateRef
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/stx.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/stx.html new file mode 100644 index 0000000000..6288eece27 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-proposal/stx.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Proposal.stx - + + + +protocols / AbstractStateReplacementProtocol / Proposal / stx
    +
    +

    stx

    + +abstract val stx: SignedTransaction
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/error.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/error.html new file mode 100644 index 0000000000..9f7df323a0 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/error.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Result.error - + + + +protocols / AbstractStateReplacementProtocol / Result / error
    +
    +

    error

    + +val error: StateReplacementRefused?
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/index.html new file mode 100644 index 0000000000..de49d73a84 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/index.html @@ -0,0 +1,48 @@ + + +AbstractStateReplacementProtocol.Result - + + + +protocols / AbstractStateReplacementProtocol / Result
    +
    +

    Result

    +data class Result
    +
    +
    +

    Properties

    + + + + + + + + + + + +
    +error +val error: StateReplacementRefused?
    +sig +val sig: WithKey?
    +

    Companion Object Functions

    + + + + + + + + + + + +
    +noError +fun noError(sig: WithKey): Result
    +withError +fun withError(error: StateReplacementRefused): Result
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/no-error.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/no-error.html new file mode 100644 index 0000000000..48aa0b8412 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/no-error.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Result.noError - + + + +protocols / AbstractStateReplacementProtocol / Result / noError
    +
    +

    noError

    + +fun noError(sig: WithKey): Result
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/sig.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/sig.html new file mode 100644 index 0000000000..3565005869 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/sig.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Result.sig - + + + +protocols / AbstractStateReplacementProtocol / Result / sig
    +
    +

    sig

    + +val sig: WithKey?
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/with-error.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/with-error.html new file mode 100644 index 0000000000..c32249c9cd --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/-result/with-error.html @@ -0,0 +1,15 @@ + + +AbstractStateReplacementProtocol.Result.withError - + + + +protocols / AbstractStateReplacementProtocol / Result / withError
    +
    +

    withError

    + +fun withError(error: StateReplacementRefused): Result
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-abstract-state-replacement-protocol/index.html b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/index.html new file mode 100644 index 0000000000..91099a6f50 --- /dev/null +++ b/docs/build/html/api/protocols/-abstract-state-replacement-protocol/index.html @@ -0,0 +1,85 @@ + + +AbstractStateReplacementProtocol - + + + +protocols / AbstractStateReplacementProtocol
    +
    +

    AbstractStateReplacementProtocol

    +abstract class AbstractStateReplacementProtocol<T>
    +

    Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. +Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these +protocols.

    +

    The Instigator assembles the transaction for state replacement and sends out change proposals to all participants +(Acceptor) of that state. If participants agree to the proposed change, they each sign the transaction. +Finally, Instigator sends the transaction containing all signatures back to each participant so they can record it and +use the new updated state for future transactions.

    +
    +
    +
    +
    +

    Types

    + + + + + + + + + + + + + + + + + + + + + + + +
    +Acceptor +abstract class Acceptor<T> : ProtocolLogic<Unit>
    +Handshake +class Handshake : AbstractRequestMessage
    +Instigator +abstract class Instigator<S : ContractState, T> : ProtocolLogic<StateAndRef<S>>
    +Proposal +interface Proposal<T>
    +Result +data class Result
    +

    Constructors

    + + + + + + + +
    +<init> +AbstractStateReplacementProtocol()

    Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. +Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these +protocols.

    +
    +

    Inheritors

    + + + + + + + +
    +NotaryChangeProtocol +object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>

    A protocol to be used for changing a states Notary. This is required since all input states to a transaction +must point to the same notary.

    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-init-.html b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-init-.html new file mode 100644 index 0000000000..7db93d79cf --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-init-.html @@ -0,0 +1,14 @@ + + +NotaryChangeProtocol.Acceptor.<init> - + + + +protocols / NotaryChangeProtocol / Acceptor / <init>
    +
    +

    <init>

    +Acceptor(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, progressTracker: ProgressTracker = tracker())
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html new file mode 100644 index 0000000000..168f35ce8d --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-c-h-a-n-g-e.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Acceptor.TOPIC_CHANGE - + + + +protocols / NotaryChangeProtocol / Acceptor / TOPIC_CHANGE
    +
    +

    TOPIC_CHANGE

    + +val TOPIC_CHANGE: String
    +Overrides Acceptor.TOPIC_CHANGE
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html new file mode 100644 index 0000000000..978bcfb00b --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Acceptor.TOPIC_INITIATE - + + + +protocols / NotaryChangeProtocol / Acceptor / TOPIC_INITIATE
    +
    +

    TOPIC_INITIATE

    + +val TOPIC_INITIATE: String
    +Overrides Acceptor.TOPIC_INITIATE
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/index.html b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/index.html new file mode 100644 index 0000000000..c70e850134 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/index.html @@ -0,0 +1,87 @@ + + +NotaryChangeProtocol.Acceptor - + + + +protocols / NotaryChangeProtocol / Acceptor
    +
    +

    Acceptor

    +class Acceptor : Acceptor<Party>
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +Acceptor(otherSide: Party, sessionIdForSend: Long, sessionIdForReceive: Long, progressTracker: ProgressTracker = tracker())
    +

    Properties

    + + + + + + + + + + + + + + + +
    +TOPIC_CHANGE +val TOPIC_CHANGE: String
    +TOPIC_INITIATE +val TOPIC_INITIATE: String
    +progressTracker +val progressTracker: ProgressTracker

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +
    +

    Inherited Properties

    + + + + + + + + + + + + + + + +
    +otherSide +val otherSide: Party
    +sessionIdForReceive +val sessionIdForReceive: Long
    +sessionIdForSend +val sessionIdForSend: Long
    +

    Inherited Functions

    + + + + + + + +
    +call +open fun call(): Unit

    This is where you fill out your business logic.

    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/progress-tracker.html b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/progress-tracker.html new file mode 100644 index 0000000000..e47486f61f --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-acceptor/progress-tracker.html @@ -0,0 +1,24 @@ + + +NotaryChangeProtocol.Acceptor.progressTracker - + + + +protocols / NotaryChangeProtocol / Acceptor / progressTracker
    +
    +

    progressTracker

    + +val progressTracker: ProgressTracker
    +Overrides Acceptor.progressTracker
    +

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +

    Note that this has to return a tracker before the protocol is invoked. You cant change your mind half way +through.

    +
    +
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-init-.html b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-init-.html new file mode 100644 index 0000000000..b1481fc359 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-init-.html @@ -0,0 +1,14 @@ + + +NotaryChangeProtocol.Instigator.<init> - + + + +protocols / NotaryChangeProtocol / Instigator / <init>
    +
    +

    <init>

    +Instigator(originalState: StateAndRef<T>, newNotary: Party, progressTracker: ProgressTracker = tracker())
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html new file mode 100644 index 0000000000..332f5fe996 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-c-h-a-n-g-e.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Instigator.TOPIC_CHANGE - + + + +protocols / NotaryChangeProtocol / Instigator / TOPIC_CHANGE
    +
    +

    TOPIC_CHANGE

    + +val TOPIC_CHANGE: String
    +Overrides Instigator.TOPIC_CHANGE
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html new file mode 100644 index 0000000000..cdb13aae53 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Instigator.TOPIC_INITIATE - + + + +protocols / NotaryChangeProtocol / Instigator / TOPIC_INITIATE
    +
    +

    TOPIC_INITIATE

    + +val TOPIC_INITIATE: String
    +Overrides Instigator.TOPIC_INITIATE
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-instigator/index.html b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/index.html new file mode 100644 index 0000000000..2bb5b8f35c --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-instigator/index.html @@ -0,0 +1,81 @@ + + +NotaryChangeProtocol.Instigator - + + + +protocols / NotaryChangeProtocol / Instigator
    +
    +

    Instigator

    +class Instigator<T : ContractState> : Instigator<T, Party>
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +Instigator(originalState: StateAndRef<T>, newNotary: Party, progressTracker: ProgressTracker = tracker())
    +

    Properties

    + + + + + + + + + + + +
    +TOPIC_CHANGE +val TOPIC_CHANGE: String
    +TOPIC_INITIATE +val TOPIC_INITIATE: String
    +

    Inherited Properties

    + + + + + + + + + + + + + + + +
    +modification +val modification: T
    +originalState +val originalState: StateAndRef<S>
    +progressTracker +open val progressTracker: ProgressTracker

    Override this to provide a ProgressTracker. If one is provided and stepped, the framework will do something +helpful with the progress reports. If this protocol is invoked as a sub-protocol of another, then the +tracker will be made a child of the current step in the parent. If its null, this protocol doesnt track +progress.

    +
    +

    Inherited Functions

    + + + + + + + +
    +call +open fun call(): StateAndRef<S>

    This is where you fill out your business logic.

    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-proposal/-init-.html b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/-init-.html new file mode 100644 index 0000000000..864c7a3abc --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/-init-.html @@ -0,0 +1,14 @@ + + +NotaryChangeProtocol.Proposal.<init> - + + + +protocols / NotaryChangeProtocol / Proposal / <init>
    +
    +

    <init>

    +Proposal(stateRef: StateRef, modification: Party, stx: SignedTransaction)
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-proposal/index.html b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/index.html new file mode 100644 index 0000000000..da2c656f97 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/index.html @@ -0,0 +1,48 @@ + + +NotaryChangeProtocol.Proposal - + + + +protocols / NotaryChangeProtocol / Proposal
    +
    +

    Proposal

    +data class Proposal : Proposal<Party>
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +Proposal(stateRef: StateRef, modification: Party, stx: SignedTransaction)
    +

    Properties

    + + + + + + + + + + + + + + + +
    +modification +val modification: Party
    +stateRef +val stateRef: StateRef
    +stx +val stx: SignedTransaction
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-proposal/modification.html b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/modification.html new file mode 100644 index 0000000000..0aba201dd3 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/modification.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Proposal.modification - + + + +protocols / NotaryChangeProtocol / Proposal / modification
    +
    +

    modification

    + +val modification: Party
    +Overrides Proposal.modification
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-proposal/state-ref.html b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/state-ref.html new file mode 100644 index 0000000000..937188b054 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/state-ref.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Proposal.stateRef - + + + +protocols / NotaryChangeProtocol / Proposal / stateRef
    +
    +

    stateRef

    + +val stateRef: StateRef
    +Overrides Proposal.stateRef
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-proposal/stx.html b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/stx.html new file mode 100644 index 0000000000..78c8426e42 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-proposal/stx.html @@ -0,0 +1,16 @@ + + +NotaryChangeProtocol.Proposal.stx - + + + +protocols / NotaryChangeProtocol / Proposal / stx
    +
    +

    stx

    + +val stx: SignedTransaction
    +Overrides Proposal.stx
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-c-h-a-n-g-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-c-h-a-n-g-e.html new file mode 100644 index 0000000000..0c16622f62 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-c-h-a-n-g-e.html @@ -0,0 +1,15 @@ + + +NotaryChangeProtocol.TOPIC_CHANGE - + + + +protocols / NotaryChangeProtocol / TOPIC_CHANGE
    +
    +

    TOPIC_CHANGE

    + +val TOPIC_CHANGE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html b/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html new file mode 100644 index 0000000000..3831614b96 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/-t-o-p-i-c_-i-n-i-t-i-a-t-e.html @@ -0,0 +1,15 @@ + + +NotaryChangeProtocol.TOPIC_INITIATE - + + + +protocols / NotaryChangeProtocol / TOPIC_INITIATE
    +
    +

    TOPIC_INITIATE

    + +val TOPIC_INITIATE: String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-notary-change-protocol/index.html b/docs/build/html/api/protocols/-notary-change-protocol/index.html new file mode 100644 index 0000000000..33875bba49 --- /dev/null +++ b/docs/build/html/api/protocols/-notary-change-protocol/index.html @@ -0,0 +1,62 @@ + + +NotaryChangeProtocol - + + + +protocols / NotaryChangeProtocol
    +
    +

    NotaryChangeProtocol

    +object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>
    +

    A protocol to be used for changing a states Notary. This is required since all input states to a transaction +must point to the same notary.

    +

    The Instigator assembles the transaction for notary replacement and sends out change proposals to all participants +(Acceptor) of that state. If participants agree to the proposed change, they each sign the transaction. +Finally, Instigator sends the transaction containing all signatures back to each participant so they can record it and +use the new updated state for future transactions.

    +
    +
    +
    +
    +

    Types

    + + + + + + + + + + + + + + + +
    +Acceptor +class Acceptor : Acceptor<Party>
    +Instigator +class Instigator<T : ContractState> : Instigator<T, Party>
    +Proposal +data class Proposal : Proposal<Party>
    +

    Properties

    + + + + + + + + + + + +
    +TOPIC_CHANGE +val TOPIC_CHANGE: String
    +TOPIC_INITIATE +val TOPIC_INITIATE: String
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-exception/-init-.html b/docs/build/html/api/protocols/-state-replacement-exception/-init-.html new file mode 100644 index 0000000000..57ccd3b864 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-exception/-init-.html @@ -0,0 +1,14 @@ + + +StateReplacementException.<init> - + + + +protocols / StateReplacementException / <init>
    +
    +

    <init>

    +StateReplacementException(error: StateReplacementRefused)
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-exception/error.html b/docs/build/html/api/protocols/-state-replacement-exception/error.html new file mode 100644 index 0000000000..c05da6c0e1 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-exception/error.html @@ -0,0 +1,15 @@ + + +StateReplacementException.error - + + + +protocols / StateReplacementException / error
    +
    +

    error

    + +val error: StateReplacementRefused
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-exception/index.html b/docs/build/html/api/protocols/-state-replacement-exception/index.html new file mode 100644 index 0000000000..7f51731f0c --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-exception/index.html @@ -0,0 +1,36 @@ + + +StateReplacementException - + + + +protocols / StateReplacementException
    +
    +

    StateReplacementException

    +class StateReplacementException : Exception
    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +StateReplacementException(error: StateReplacementRefused)
    +

    Properties

    + + + + + + + +
    +error +val error: StateReplacementRefused
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/-init-.html b/docs/build/html/api/protocols/-state-replacement-refused/-init-.html new file mode 100644 index 0000000000..f9451cb809 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/-init-.html @@ -0,0 +1,15 @@ + + +StateReplacementRefused.<init> - + + + +protocols / StateReplacementRefused / <init>
    +
    +

    <init>

    +StateReplacementRefused(identity: Party, state: StateRef, detail: String?)
    +

    Thrown when a participant refuses proposed the state replacement

    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/detail.html b/docs/build/html/api/protocols/-state-replacement-refused/detail.html new file mode 100644 index 0000000000..8d7304e88c --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/detail.html @@ -0,0 +1,15 @@ + + +StateReplacementRefused.detail - + + + +protocols / StateReplacementRefused / detail
    +
    +

    detail

    + +val detail: String?
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/identity.html b/docs/build/html/api/protocols/-state-replacement-refused/identity.html new file mode 100644 index 0000000000..50be129ce5 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/identity.html @@ -0,0 +1,15 @@ + + +StateReplacementRefused.identity - + + + +protocols / StateReplacementRefused / identity
    +
    +

    identity

    + +val identity: Party
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/index.html b/docs/build/html/api/protocols/-state-replacement-refused/index.html new file mode 100644 index 0000000000..f924b5a88e --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/index.html @@ -0,0 +1,61 @@ + + +StateReplacementRefused - + + + +protocols / StateReplacementRefused
    +
    +

    StateReplacementRefused

    +class StateReplacementRefused
    +

    Thrown when a participant refuses proposed the state replacement

    +
    +
    +

    Constructors

    + + + + + + + +
    +<init> +StateReplacementRefused(identity: Party, state: StateRef, detail: String?)

    Thrown when a participant refuses proposed the state replacement

    +
    +

    Properties

    + + + + + + + + + + + + + + + +
    +detail +val detail: String?
    +identity +val identity: Party
    +state +val state: StateRef
    +

    Functions

    + + + + + + + +
    +toString +fun toString(): String
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/state.html b/docs/build/html/api/protocols/-state-replacement-refused/state.html new file mode 100644 index 0000000000..c0e3915d45 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/state.html @@ -0,0 +1,15 @@ + + +StateReplacementRefused.state - + + + +protocols / StateReplacementRefused / state
    +
    +

    state

    + +val state: StateRef
    +
    +
    + + diff --git a/docs/build/html/api/protocols/-state-replacement-refused/to-string.html b/docs/build/html/api/protocols/-state-replacement-refused/to-string.html new file mode 100644 index 0000000000..928400ff58 --- /dev/null +++ b/docs/build/html/api/protocols/-state-replacement-refused/to-string.html @@ -0,0 +1,15 @@ + + +StateReplacementRefused.toString - + + + +protocols / StateReplacementRefused / toString
    +
    +

    toString

    + +fun toString(): String
    +
    +
    + + diff --git a/docs/build/html/api/protocols/index.html b/docs/build/html/api/protocols/index.html new file mode 100644 index 0000000000..b4414f9f07 --- /dev/null +++ b/docs/build/html/api/protocols/index.html @@ -0,0 +1,51 @@ + + +protocols - + + + +protocols
    +
    +

    Package protocols

    +

    Types

    + + + + + + + + + + + + + + + +
    +AbstractStateReplacementProtocol +abstract class AbstractStateReplacementProtocol<T>

    Abstract protocol to be used for replacing one state with another, for example when changing the notary of a state. +Notably this requires a one to one replacement of states, states cannot be split, merged or issued as part of these +protocols.

    +
    +NotaryChangeProtocol +object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>

    A protocol to be used for changing a states Notary. This is required since all input states to a transaction +must point to the same notary.

    +
    +StateReplacementRefused +class StateReplacementRefused

    Thrown when a participant refuses proposed the state replacement

    +
    +

    Exceptions

    + + + + + + + +
    +StateReplacementException +class StateReplacementException : Exception
    + + diff --git a/docs/build/html/building-the-docs.html b/docs/build/html/building-the-docs.html index 45e63161ed..ec6da11f84 100644 --- a/docs/build/html/building-the-docs.html +++ b/docs/build/html/building-the-docs.html @@ -89,8 +89,8 @@
  • What’s included?
  • Getting set up
  • Data model
  • -
  • Transaction Data Types
  • -
  • Consensus Model
  • +
  • Data types
  • +
  • Consensus model
  • Networking and messaging
  • Running the demos
  • Node administration
  • @@ -102,6 +102,7 @@
  • Writing a contract
  • Protocol state machines
  • Writing oracle services
  • +
  • Event scheduling

Appendix

Appendix

  • Building the documentation
  • @@ -325,6 +328,38 @@ really necessary. In other words, don’t do this:

    The latter is easier to catch and handle if later necessary, and the type name should explain what went wrong.

    Note that Kotlin does not require exception types to be declared in method prototypes like Java does.

    +
    +

    5. Properties

    +

    Where we want a public property to have one super-type in public and another sub-type in private (or internal), perhaps +to expose additional methods with a greater level of access to the code within the enclosing class, the style should be:

    +
    class PrivateFoo : PublicFoo
    +
    +private val _foo = PrivateFoo()
    +val foo: PublicFoo get() = _foo
    +
    +
    +

    Notably:

    +
      +
    • The public property should have an explicit and more restrictive type, most likely a super class or interface.
    • +
    • The private, backed property should begin with underscore but otherwise have the same name as the public property. +The underscore resolves a potential property name clash, and avoids naming such as “privateFoo”. If the type or use +of the private property is different enough that there is no naming collision, prefer the distinct names without +an underscore.
    • +
    • The underscore prefix is not a general pattern for private properties.
    • +
    • The public property should not have an additional backing field but use “get()” to return an appropriate copy of the +private field.
    • +
    • The public property should optionally wrap the returned value in an immutable wrapper, such as Guava’s immutable +collection wrappers, if that is appropriate.
    • +
    • If the code following “get()” is succinct, prefer a one-liner formatting of the public property as above, otherwise +put the “get()” on the line below, indented.
    • +
    +
    +
    +

    6. Compiler warnings

    +

    We do not allow compiler warnings, except in the experimental module where the usual standards do not apply and warnings +are suppressed. If a warning exists it should be either fixed or suppressed using @SuppressWarnings and if suppressed +there must be an accompanying explanation in the code for why the warning is a false positive.

    +
    diff --git a/docs/build/html/consensus.html b/docs/build/html/consensus.html index e573477af5..580dc8a601 100644 --- a/docs/build/html/consensus.html +++ b/docs/build/html/consensus.html @@ -8,7 +8,7 @@ - Consensus Model — R3 Corda latest documentation + Consensus model — R3 Corda latest documentation @@ -32,7 +32,7 @@ - + @@ -90,13 +90,15 @@
  • What’s included?
  • Getting set up
  • Data model
  • -
  • Transaction Data Types
  • -
  • Consensus Model

    Appendix

      @@ -149,7 +152,7 @@
      • Docs »
      • -
      • Consensus Model
      • +
      • Consensus model
      • @@ -164,11 +167,11 @@
        -

        Consensus Model

        +

        Consensus model

        The fundamental unit of consensus in Corda is the state. The concept of consensus can be divided into two parts:

        1. Consensus over state validity – parties can reach certainty that a transaction defining output states is accepted by the contracts pointed to by the states and has all the required signatures. This is achieved by parties independently running the same contract code and validation logic (as described in data model)
        2. -
        3. Consensus over state uniqueness – parties can reach certainty the the output states created in a transaction are the unique successors to the input states consumed by that transaction (in other words – a state has not been used as an input by more than one transaction)
        4. +
        5. Consensus over state uniqueness – parties can reach certainty the output states created in a transaction are the unique successors to the input states consumed by that transaction (in other words – a state has not been used as an input by more than one transaction)

        This article presents an initial model for addressing the uniqueness problem.

        @@ -178,75 +181,97 @@

        Notary

        We introduce the concept of a Notary, which is an authority responsible for attesting that for a given transaction, it had not signed another transaction consuming any of its input states. -The data model is extended so that every state has an appointed Notary:

        -
        interface ContractState {
        -    /** Contract by which the state belongs */
        -    val contract: Contract
        -
        -    /** Identity of the notary that ensures this state is not used as an input to a transaction more than once */
        -    val notary: Party
        +The data model is extended so that every state has an appointed notary:

        +
        /**
        + * A wrapper for [ContractState] containing additional platform-level state information.
        + * This is the definitive state that is stored on the ledger and used in transaction outputs
        + */
        +data class TransactionState<out T : ContractState>(
        +        /** The custom contract state */
        +        val data: T,
        +        /** Identity of the notary that ensures the state is not used as an input to a transaction more than once */
        +        val notary: Party) {
        +    ...
         }
         
        -

        All transactions have to be signed by their input state Notary for the output states to be valid (apart from issue transactions, containing no input states).

        +

        All transactions have to be signed by their input state notary for the output states to be valid (apart from issue transactions, containing no input states).

        Note

        -

        The Notary is a logical concept and can itself be a distributed entity, potentially a cluster maintained by mutually distrusting parties

        +

        The notary is a logical concept and can itself be a distributed entity, potentially a cluster maintained by mutually distrusting parties

        -

        When the Notary is requested to sign a transaction, it either signs over it, attesting that the outputs are the unique successors of the inputs, +

        When the notary is requested to sign a transaction, it either signs over it, attesting that the outputs are the unique successors of the inputs, or provides conflict information for any input state that had been consumed by another transaction it had signed before. -In doing so, the Notary provides the point of finality in the system. Until the Notary signature is obtained, parties cannot be sure that an equally valid, but conflicting transaction, +In doing so, the notary provides the point of finality in the system. Until the notary signature is obtained, parties cannot be sure that an equally valid, but conflicting transaction, will not be regarded as confirmed. After the signature is obtained, the parties know that the inputs to this transaction have been uniquely consumed by this transaction. Hence it is the point at which we can say finality has occurred.

        -
        -

        Validation

        -

        The Notary does not validate transaction integrity (i.e. does not run contracts or check signatures) to minimise the exposed data. -Validation would require the caller to reveal the whole transaction history chain, resulting in a privacy leak.

        -

        However, this makes it open to “denial of state” attacks, where a party could submit any invalid transaction to the Notary and thus “block” someone else’s states. -That is partially alleviated by requiring the calling party to authenticate and storing its identity for the request. -The conflict information returned by the Notary specifies the consuming transaction id along with the identity of the party that had requested the commit. -If the conflicting transaction is valid, the current one gets aborted; if not – a dispute can be raised and the input states of the conflicting invalid transaction are “un-committed” (to be covered by legal process).

        -
        -

        Note

        -

        At present the Notary can see the entire transaction, but we have a separate piece of work to replace the parts of the transaction it does not require knowing about with hashes (only input references, timestamp information, overall transaction ID and the necessary digests of the rest of the transaction to prove that the referenced inputs/timestamps really do form part of the stated transaction ID should be visible).

        -
        -
        -

        Multiple Notaries

        -

        More than one Notary can exist in the network. This gives the following benefits:

        +

        Multiple notaries

        +

        More than one notary can exist in the network. This gives the following benefits:

        • Custom behaviour. We can have both validating and privacy preserving Notaries – parties can make a choice based on their specific requirements
        • Load balancing. Spreading the transaction load over multiple Notaries will allow higher transaction throughput in the platform overall
        • -
        • Low latency. Latency could be minimised by choosing a Notary physically closer the transacting parties
        • +
        • Low latency. Latency could be minimised by choosing a notary physically closer the transacting parties
        -

        A transaction should only be signed by a Notary if all of its input states point to it. -In cases where a transaction involves states controlled by multiple Notaries, the states first have to be repointed to the same notary. -This is achieved by using a special type of transaction that doesn’t modify anything but the Notary pointer of the state. -Ensuring that all input states point to the same Notary is the responsibility of each involved party +

        A transaction should only be signed by a notary if all of its input states point to it. +In cases where a transaction involves states controlled by multiple notaries, the states first have to be repointed to the same notary. +This is achieved by using a special type of transaction that doesn’t modify anything but the notary pointer of the state. +Ensuring that all input states point to the same notary is the responsibility of each involved party (it is another condition for an output state of the transaction to be valid)

        +
        +

        Validation

        +

        One of the design decisions for a notary is whether or not to validate a transaction before committing its input states.

        +

        If a transaction is not checked for validity, it opens the platform to “denial of state” attacks, where anyone can build an invalid transaction consuming someone else’s states and submit it to the notary to get the states “blocked”. +However, validation of a transaction requires the notary to be able to see the full contents of the transaction in question and its dependencies. +This is an obvious privacy leak.

        +

        Our platform is flexible and we currently support both validating and non-validating notary implementations – a party can select which one to use based on its own privacy requirements.

        +
        +

        Note

        +

        In the non-validating model the “denial of state” attack is partially alleviated by requiring the calling party to authenticate and storing its identity for the request.

        +
        +
        +
        The conflict information returned by the Notary specifies the consuming transaction id along with the identity of the party that had requested the commit.
        +
        If the conflicting transaction is valid, the current one gets aborted; if not – a dispute can be raised and the input states of the conflicting invalid transaction are “un-committed” (to be covered by legal process).
        +
        +
        +

        Note

        +

        At present all notaries can see the entire contents of a transaction, but we have a separate piece of work to replace the parts of the transaction it does not require knowing about with hashes (only input references, timestamp information, overall transaction ID and the necessary digests of the rest of the transaction to prove that the referenced inputs/timestamps really do form part of the stated transaction ID should be visible).

        +
        +

        Timestamping

        -

        In this model the Notary also acts as a Timestamping Authority, verifying the transaction timestamp command.

        +

        In this model the notary also acts as a Timestamping Authority, verifying the transaction timestamp command.

        For a timestamp to be meaningful, its implications must be binding on the party requesting it. A party can obtain a timestamp signature in order to prove that some event happened before/on/or after a particular point in time. However, if the party is not also compelled to commit to the associated transaction, it has a choice of whether or not to reveal this fact until some point in the future. -As a result, we need to ensure that the Notary either has to also sign the transaction within some time tolerance, +As a result, we need to ensure that the notary either has to also sign the transaction within some time tolerance, or perform timestamping and notarisation at the same time, which is the chosen behaviour for this model.

        -
        -

        Implementation & Usage

        -

        At present we have single basic implementation of a Notary that uses a UniquenessProvider storing committed input states in memory:

        -
        class InMemoryUniquenessProvider() : UniquenessProvider {
        -    /** For each input state store the consuming transaction information */
        -    private val committedStates = HashMap<StateRef, ConsumingTx>()
        -
        -    override fun commit(tx: WireTransaction, callerIdentity: Party) {
        -        ...
        -    }
        +
        +

        Running a Notary Service

        +

        At present we have two basic implementations that store committed input states in memory:

        +
          +
        • SimpleNotaryService – commits the provided transaction without any validation
        • +
        • ValidatingNotaryService – retrieves and validates the whole transaction history (including the given transaction) before committing
        • +
        +

        To run one of these services the node has to simply specify either SimpleNotaryService.Type or ValidatingNotaryService.Type in its advertisedServices set, and the correct type will be initialised.

        +
        +
        +

        Obtaining a signature

        +

        To obtain a signature from a notary use NotaryProtocol.Client, passing in a WireTransaction. +The protocol will work out which notary needs to be called based on the input states and the timestamp command. +For example, the following snippet can be used when writing a custom protocol:

        +
        fun getNotarySignature(wtx: WireTransaction): DigitalSignature.LegallyIdentifiable {
        +    return subProtocol(NotaryProtocol.Client(wtx))
         }
        -...
        +
        +
        +

        On conflict the NotaryProtocol with throw a NotaryException containing the conflict details:

        +
        /** Specifies the consuming transaction for the conflicting input state */
        +data class Conflict(val stateHistory: Map<StateRef, ConsumingTx>)
        +
         /**
          * Specifies the transaction id, the position of the consumed state in the inputs, and
          * the caller identity requesting the commit
        @@ -254,20 +279,25 @@ or perform timestamping and notarisation at the same time, which is the
         data class ConsumingTx(val id: SecureHash, val inputIndex: Int, val requestingParty: Party)
         
        -

        To obtain a signature from a Notary use NotaryProtocol, passing in a WireTransaction. -The protocol will work out which Notary needs to be called based on the input states and the timestamp command. -For example, the following snippet can be used when writing a custom protocol:

        -
        private fun getNotarySignature(wtx: WireTransaction): DigitalSignature.LegallyIdentifiable {
        -    return subProtocol(NotaryProtocol(wtx))
        +

        Conflict handling and resolution is currently the responsibility of the protocol author.

        +
        +
        +

        Changing notaries

        +

        To change the notary for an input state, use the NotaryChangeProtocol. For example:

        +
        fun changeNotary(originalState: StateAndRef<ContractState>,
        +                 newNotary: Party): StateAndRef<ContractState> {
        +    val protocol = NotaryChangeProtocol.Instigator(originalState, newNotary)
        +    return subProtocol(protocol)
         }
         
        -

        On conflict the NotaryProtocol with throw a NotaryException containing the conflict details:

        -
        /** Specifies the consuming transaction for the conflicting input state */
        -data class Conflict(val stateHistory: Map<StateRef, ConsumingTx>)
        -
        -
        -

        Conflict handling and resolution is currently the responsibility of the protocol author.

        +

        The protocol will:

        +
          +
        1. Construct a transaction with the old state as the input and the new state as the output
        2. +
        3. Obtain signatures from all participants (a participant is any party that is able to consume this state in a valid transaction, as defined by the state itself)
        4. +
        5. Obtain the old notary signature
        6. +
        7. Record and distribute the final transaction to the participants so that everyone possesses the new state
        8. +
        @@ -281,7 +311,7 @@ For example, the following snippet can be used when writing a custom protocol:Next - Previous + Previous
        diff --git a/docs/build/html/data-model.html b/docs/build/html/data-model.html index 6301b9affb..5ee70359cb 100644 --- a/docs/build/html/data-model.html +++ b/docs/build/html/data-model.html @@ -31,7 +31,7 @@ - + @@ -99,8 +99,8 @@
      • Cons
      -
    • Transaction Data Types
    • -
    • Consensus Model
    • +
    • Data types
    • +
    • Consensus model
    • Networking and messaging
    • Running the demos
    • Node administration
    • @@ -112,6 +112,7 @@
    • Writing a contract
    • Protocol state machines
    • Writing oracle services
    • +
    • Event scheduling

    Appendix

      @@ -404,7 +405,7 @@ something that can be trivially fixed with data model changes.

    Appendix

      diff --git a/docs/build/html/getting-set-up.html b/docs/build/html/getting-set-up.html index ef1ba8531f..b517ec5d6c 100644 --- a/docs/build/html/getting-set-up.html +++ b/docs/build/html/getting-set-up.html @@ -94,8 +94,8 @@
  • Data model
  • -
  • Transaction Data Types
  • -
  • Consensus Model
  • +
  • Data types
  • +
  • Consensus model
  • Networking and messaging
  • Running the demos
  • Node administration
  • @@ -107,6 +107,7 @@
  • Writing a contract
  • Protocol state machines
  • Writing oracle services
  • +
  • Event scheduling
  • Appendix

    Appendix

      @@ -194,21 +195,23 @@ following hypothesis:

    • Cons
    -
  • Transaction Data Types
  • Building the documentation

    Appendix

      @@ -162,44 +163,58 @@

      What’s included?

      -

      The current prototype consists of a small amount of code that defines:

      -
        -
      • Key data structures.
      • -
      • Algorithms that work with them, such as serialising, hashing, signing, and verification of the signatures.
      • -
      • Two smart contracts that implement a notion of a cash claim and basic commercial paper (implemented twice, in two -different programming languages). These are simplified versions of the real things.
      • -
      • Unit tests that check the algorithms do what is expected, and which verify the behaviour of the smart contracts.
      • -
      • API documentation and tutorials (what you’re reading)
      • -
      • A simple standalone node that uses an embedded message queue broker as its P2P messaging layer.
      • -
      • A trading demo that runs the node in either a listening/buying mode, or a connecting/selling mode, and swaps some -fake commercial paper assets for some self-issued IOU cash, using a generic protocol framework.
      • -
      • It also includes two oracles: one for precise timestamping and another for interest rate swaps.
      • +

        The Corda prototype currently includes:

        +
          +
        • A peer to peer network with message persistence and delivery retries.

          +
        • +
        • Key data structures for defining contracts and states.

          +
        • +
        • +
          Smart contracts:
          +
            +
          • Cash
          • +
          • Cash obligations
          • +
          • Interest rate swaps
          • +
          • Commercial paper (implemented in both Java and Kotlin for comparison)
          • +
          +
          +
          +
        • +
        • Algorithms that work with them, such as serialising, hashing, signing, and verification of the signatures.

          +
        • +
        • API documentation and tutorials (what you’re reading).

          +
        • +
        • A business process orchestration framework.

          +
        • +
        • Notary infrastructure for precise timestamping, and elimination of double spending without a blockchain.

          +
        • +
        • A simple REST API.

          +

        Some things it does not currently include but should gain later are:

        • Sandboxing, distribution or publication of smart contract code
        • -
        • A peer to peer network
        • Database persistence
        • -
        • An API for integrating external software
        • A user interface for administration
        • Many other things
        -

        You can browse the JIRA bug tracker.

        The prototype’s goal is rapid exploration of ideas. Therefore in places it takes shortcuts that a production system would not in order to boost productivity:

        • It uses an object graph serialization framework instead of a well specified, vendor neutral protocol.
        • -
        • It uses secp256r1, an obsolete elliptic curve.
        • It uses the default, out of the box Apache Artemis MQ protocol instead of AMQP/1.0 (although switching should be easy)
        • +
        • There is no inter-node SSL or other encryption yet.

        Contracts

        The primary goal of this prototype is to implement various kinds of contracts and verify that useful business logic can be expressed with the data model, developing and refining an API along the way. To that end there are currently -two contracts in the repository:

        +four contracts in the repository:

        1. Cash
        2. Commercial paper
        3. +
        4. Nettable obligations
        5. +
        6. Interest rate swaps

        Cash implements the idea of a claim on some quantity of deposits at some institutional party, denominated in some currency, identified by some deposit reference. A deposit reference is an opaque byte array which is usable by @@ -212,11 +227,12 @@ at which they may be redeemed. The contract allows the paper to be issued, trade contract is implemented twice, once in Java and once in a language called Kotlin.

        InterestRateSwap implements a vanilla OTC same currency bilateral fixed / floating leg swap. For further details, see The Interest Rate Swap Contract

        +

        Obligation implements a bilaterally or multi-laterally nettable, fungible obligation that can default.

        Each contract comes with unit tests.

        Kotlin

        -

        The prototype is written in a language called Kotlin. Kotlin is a language that targets the JVM +

        Corda is written in a language called Kotlin. Kotlin is a language that targets the JVM and can be thought of as a simpler Scala, with much better Java interop. It is developed by and has commercial support from JetBrains, the makers of the IntelliJ IDE and other popular developer tools.

        As Kotlin is very new, without a doubt you have not encountered it before. Don’t worry: it is designed as a better @@ -224,13 +240,6 @@ Java for industrial use and as such, the syntax was carefully designed to be rea the language, after only a few minutes of introduction.

        Due to the seamless Java interop the use of Kotlin to extend the platform is not required and the tutorial shows how to write contracts in both Kotlin and Java. You can read more about why Kotlin is a potentially strong successor to Java here.

        -

        Kotlin programs use the regular Java standard library and ordinary Java frameworks. Frameworks used at this time are:

        -
          -
        • JUnit for unit testing
        • -
        • Kryo for serialisation (this is not intended to be permanent)
        • -
        • Gradle for the build
        • -
        • Guava for a few utility functions
        • -
      diff --git a/docs/build/html/irs.html b/docs/build/html/irs.html index 9eef4f819f..948ac804e7 100644 --- a/docs/build/html/irs.html +++ b/docs/build/html/irs.html @@ -90,8 +90,8 @@
    • What’s included?
    • Getting set up
    • Data model
    • -
    • Transaction Data Types
    • -
    • Consensus Model
    • +
    • Data types
    • +
    • Consensus model
    • Networking and messaging
    • Running the demos
    • Node administration
    • @@ -107,6 +107,7 @@
    • Writing a contract
    • Protocol state machines
    • Writing oracle services
    • +
    • Event scheduling

    Appendix

    Appendix

    Appendix

      @@ -110,6 +111,7 @@
    • Steps to cut a release
    • Release notes
    • @@ -165,12 +167,96 @@

      Here are brief summaries of what’s changed between each snapshot release.

      Unreleased

      -

      Here are changes in git master that haven’t yet made it to a snapshot release:

      +

      There are currently no unreleased changes.

      +
      +
      +

      Milestone 1

      +

      Highlights of this release:

      +
        +
      • Event scheduling. States in the ledger can now request protocols to be invoked at particular times, for states +considered relevant by the wallet.

        +
      • +
      • Upgrades to the notary/consensus service support:

        +
        +
          +
        • There is now a way to change the notary controlling a state.
        • +
        • You can pick between validating and non-validating notaries, these let you select your privacy/robustness tradeoff.
        • +
        +
        +
      • +
      • A new obligation contract that supports bilateral and multilateral netting of obligations, default tracking and +more.

        +
      • +
      • Improvements to the financial type system, with core classes and contracts made more generic.

        +
      • +
      • Switch to a better digital signature algorithm: ed25519 instead of the previous JDK default of secp256r1.

        +
      • +
      • A new integration test suite.

        +
      • +
      • A new Java unit testing DSL for contracts, similar in spirit to the one already developed for Kotlin users (which +depended on Kotlin specific features).

        +
      • +
      • An experimental module, where developers who want to work with the latest Corda code can check in contracts/cordapp +code before it’s been fully reviewed. Code in this module has compiler warnings suppressed but we will still make +sure it compiles across refactorings.

        +
      • +
      • Persistence improvements: transaction data is now stored to disk and automatic protocol resume is now implemented.

        +
      • +
      • Many smaller bug fixes, cleanups and improvements.

        +
      • +
      +

      We have new documentation on:

        -
      • The cash contract has moved from com.r3corda.contracts to com.r3corda.contracts.cash.
      • -
      • Amount class is now generic, to support non-currency types (such as assets, or currency with additional information).
      • -
      • Refactored the Cash contract to have a new FungibleAsset superclass, to model all countable assets that can be merged -and split (currency, barrels of oil, etc.)
      • +
      • Event scheduling
      • +
      • Data types
      • +
      • Consensus model
      • +
      +

      Summary of API changes (not exhaustive):

      +
        +
      • Notary/consensus service:

        +
        +
          +
        • NotaryService is now extensible.
        • +
        • Every ContractState now has to specify a participants field, which is a list of parties that are able to +consume this state in a valid transaction. This is used for e.g. making sure all relevant parties obtain the updated +state when changing a notary.
        • +
        • Introduced TransactionState, which wraps ContractState, and is used when defining a transaction output. +The notary field is moved from ContractState into TransactionState.
        • +
        • Every transaction now has a type field, which specifies custom build & validation rules for that transaction type. +Currently two types are supported: General (runs the default build and validation logic) and NotaryChange ( +contract code is not run during validation, checks that the notary field is the only difference between the +inputs and outputs). +TransactionBuilder() is now abstract, you should use TransactionType.General.Builder() for building transactions.
        • +
        +
        +
      • +
      • The cash contract has moved from com.r3corda.contracts to com.r3corda.contracts.cash

        +
      • +
      • Amount class is now generic, to support non-currency types such as physical assets. Where you previously had just +Amount, you should now use Amount<Currency>.

        +
      • +
      • Refactored the Cash contract to have a new FungibleAsset superclass, to model all countable assets that can be merged +and split (currency, barrels of oil, etc.)

        +
      • +
      • Messaging:

        +
        +
          +
        • addMessageHandler now has a different signature as part of error handling changes.
        • +
        • If you want to return nothing to a protocol, use Ack instead of Unit from now on.
        • +
        +
        +
      • +
      • In the IRS contract, dateOffset is now an integer instead of an enum.

        +
      • +
      • In contracts, you now use tx.getInputs and tx.getOutputs instead of getInStates and getOutStates. This is +just a renaming.

        +
      • +
      • A new NonEmptySet type has been added for cases where you wish to express that you have a collection of unique +objects which cannot be empty.

        +
      • +
      • Please use the global newSecureRandom() function rather than instantiating your own SecureRandom’s from now on, as +the custom function forces the use of non-blocking random drivers on Linux.

        +
      diff --git a/docs/build/html/release-process.html b/docs/build/html/release-process.html index 96de61e5fe..ae657bc878 100644 --- a/docs/build/html/release-process.html +++ b/docs/build/html/release-process.html @@ -32,7 +32,7 @@ - + @@ -90,8 +90,8 @@
    • What’s included?
    • Getting set up
    • Data model
    • -
    • Transaction Data Types
    • -
    • Consensus Model
    • +
    • Data types
    • +
    • Consensus model
    • Networking and messaging
    • Running the demos
    • Node administration
    • @@ -103,6 +103,7 @@
    • Writing a contract
    • Protocol state machines
    • Writing oracle services
    • +
    • Event scheduling

    Appendix

      @@ -206,7 +207,7 @@ Minor changes to the branch don’t have to be announced unless it’d b Next - Previous + Previous diff --git a/docs/build/html/robots.txt b/docs/build/html/robots.txt new file mode 100644 index 0000000000..1f53798bb4 --- /dev/null +++ b/docs/build/html/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Disallow: / diff --git a/docs/build/html/running-the-demos.html b/docs/build/html/running-the-demos.html index 4f5080aea5..2273488cb4 100644 --- a/docs/build/html/running-the-demos.html +++ b/docs/build/html/running-the-demos.html @@ -90,8 +90,8 @@
    • What’s included?
    • Getting set up
    • Data model
    • -
    • Transaction Data Types
    • -
    • Consensus Model
    • +
    • Data types
    • +
    • Consensus model
    • Networking and messaging
    • Running the demos

      Appendix

      Appendix

        diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index b6ba315656..784423c143 100644 --- a/docs/build/html/searchindex.js +++ b/docs/build/html/searchindex.js @@ -1 +1 @@ -Search.setIndex({envversion:47,filenames:["building-the-docs","codestyle","consensus","data-model","getting-set-up","index","inthebox","irs","messaging","node-administration","oracles","protocol-state-machines","release-notes","release-process","running-the-demos","transaction-data-types","tutorial-contract","visualiser","where-to-start"],objects:{},objnames:{},objtypes:{},terms:{"0_xx":4,"1mb":11,"8u45":4,"_before_":11,"_do_":11,"_is_":11,"_mbeans_":9,"abstract":[3,11],"boolean":[3,16],"break":[10,13,16],"byte":[1,3,6,11],"case":[1,2,3,8,10,11,15,16],"catch":[1,4,11],"class":[1,2,5,7,8,10,11,12,15],"default":[1,4,6,11,14,16],"export":[9,11,18],"final":[2,3,4,7,8,11,16],"float":[6,7],"function":[1,3,5,6,7,8,10,11,14,15],"import":[1,3,4,8,11,13,16,18],"instanceof":16,"int":[1,2,16],"long":[1,3,8,11,16],"new":[1,3,4,5,6,7,8,9,11,12,13,16,18],"null":[10,16],"public":[1,3,6,8,9,10,11,15,16],"return":[1,2,7,8,9,10,11,16,18],"short":[8,13,16],"static":[3,10,11,16,18],"switch":[6,11,16],"throw":[1,2,10,11,16],"transient":11,"true":[3,8,10,16,17],"try":[1,3,11,14,16,17,18],"var":16,"void":16,"while":15,abil:[3,8],abl:[3,8,10],abort:2,about:[1,2,3],abov:[3,7,8,11,16],absolut:3,abstractnod:10,accept:[1,2,3,8,11,16],acceptablepric:11,access:[3,4,8,9,10,11,16],accid:11,accident:1,accord:18,accordingli:8,account:[3,15],accrual:7,accur:10,accuraci:3,achiev:[2,3,8],acknowledg:11,across:[3,11],act:[2,3,8,10,11],action:[16,18],activ:[7,14],actor:[1,3,11],actual:[4,7,8,10,11,16],adapt:[1,10,11],add:[1,8,9,11,15,16],addarg:16,addcommand:11,addinputst:[11,16],addit:[1,3,12,15,16],addition:[10,11,13],addmessagehandl:8,addoutputst:[11,16],address:[2,3,8,11,16],adjust:[1,7,18],admin:4,administr:[5,6],advanc:[5,7],advantag:3,adventur:18,advertis:10,advic:13,affect:[4,10],affection:16,affinityexecutor:1,afraid:1,after:[2,3,4,6,7,10,11,16,17],again:[3,7,8,10,11,14,16],against:[3,7,11,16],agent:9,aggreg:[3,16],agre:[7,11],agreement:[3,7,15],ahead:11,aim:[1,3],algorithm:[3,6,16,17],alic:[16,17],aliceaddr:8,alicegetsback:[16,17],alicenod:8,aliv:11,all:[0,1,2,3,4,7,8,9,10,11,12,13,14,16,18],allevi:2,allow:[1,2,3,6,7,10,11,15,16,18],allpossiblerecipi:8,almost:[11,16],along:[2,6,8,10,11,16],alreadi:[1,10,11,16],alright:11,also:[1,2,3,4,6,7,8,9,11,14,15,16,18],alt:16,alter:[11,16],altern:[0,1,9],although:[3,6,7,8,16,18],alwai:[1,3,9,11,16],amounnt:11,amount:[3,5,6,7,11,12],amqp:6,analysi:3,andresen:3,ani:[1,2,3,7,8,9,10,11,13,15,16,18],annot:[1,11,16],announc:13,anonym:3,anoth:[2,4,6,9,10,11,16],answer:[1,10],anticip:1,anybodi:3,anyon:16,anyth:[2,3,8,10,11,16],anywher:[8,10,16],apach:[6,8],apart:2,api:[0,1,5,6,9,10,11,13,14],app:[9,13,18],appear:16,append:9,appendix:5,appli:[1,3,7,16],applic:[3,10,18],applyfix:7,appoint:2,approach:[3,5],appropri:8,approv:[3,11],arbitrari:[1,3,10,11,16],arbitrarili:6,architectur:[5,10],area:[8,15],aren:[11,16,18],arg:[16,17],arguabl:10,argument:[1,3,8,11,16],aris:3,around:[3,8,10,11,13,15,16,17],arrai:[3,6,11],arrang:11,arriv:[10,11],arrow:[4,7],artemi:6,articl:[2,3,8,10,11,18],artifact:16,ask:[1,11,16],aspect:[11,18],assembl:3,assemblesharedtx:11,asset:[5,6,11,12,15],assetforsal:11,assetmismatchexcept:11,assettosel:11,assettypenam:11,assign:10,assist:[11,16,17],associ:[2,3,8,15,16],assum:[3,10,11,16],assumpt:11,atom:[3,10,11,14,16],attach:[3,5],attack:2,attempt:[3,4,5,8,11],attent:11,attest:[2,10],attribut:1,audit:[3,11],authent:2,authenticatedobject:[15,16],author:[1,2,3,8,11,13,18],authoris:11,auto:[1,16],autom:[3,16,18],automat:[0,8,11,16,18],avail:[0,7,8,9,10,13,16],avoid:[1,3,11],awai:[3,11,14],awar:[1,11],awg:13,awkward:[1,11],axi:7,back:[3,10,11,15,16],backend:8,background:[1,3,8],backport:13,backtick:16,backward:[11,13],bad:[1,11,16],balanc:[2,3,16],band:11,bandwidth:1,bank:[3,7,15,18],bankrupt:16,bankruptci:[3,10],barrel:12,base:[1,2,3,5,7,8,15],basi:[7,9],basic:[1,2,3,5,6,8],bat:14,bear:[11,16],beauti:17,becaus:[1,3,4,8,9,10,11,16],becom:[1,3,7,11,13],been:[2,3,4,7,10,11,13,16],befor:[2,3,6,7,10,11,13,15,16],beforehand:14,begin:[3,14,16,18],behav:16,behaviour:[2,6,9],behind:[11,16],belong:2,below:[3,7,11,18],benefit:[2,11,16],best:[1,14,18],bet:10,better:[1,5,6,16,17],between:[1,3,7,8,10,11,12,13,14,15,16],beyond:[3,16],big:[1,3,11,16],bigdecim:10,bilater:[6,7],bill:16,bin:14,binari:[3,10],bind:[2,3,10],bip:3,bit:[11,16,17,18],bitbucket:4,bitcoinj:11,blah:1,blank:[1,16],block:[1,2,3,5,8,10,11,16],blockchain:[3,11],bloom:1,bloomfilt:1,blow:14,blue:[7,17],bob:16,bobaddr:8,bobnod:8,bodi:1,boil:3,bond:16,bookkeep:[6,16],boost:6,borrow:17,both:[2,3,6,7,8,10,11,14,16],bottom:11,bound:[10,11],box:[6,18],branch:13,breach:3,bread:18,breadth:11,brief:12,briefli:[8,17],bring:3,broadcast:[3,8],broke:1,broker:6,brows:6,bug:[1,6,13],bugfix:13,bui:[6,11,18],builder:16,built:[11,16],bulk:3,bullet:1,bunch:[14,16],bundl:3,busi:[3,6,8,10,11,15,16,18],businesscalendar:15,butter:18,buyer:5,buyersessionid:11,bytearrai:8,bytecod:[3,11,16],cach:8,calcul:[7,11,15,16],calendar:[7,10,15],calibr:3,call:[1,2,3,6,7,8,9,11,13,16],callback:[1,8,11],caller:[2,16],callerident:2,came:11,camel:1,can:[0,1,2,3,4,6,7,8,9,10,11,12,14,15,16,17,18],cannot:[2,3,4,10,16],capabl:16,capit:1,capitan:0,care:[1,3,8,10,11],carefulli:6,cash:[3,5,6,7,10,11,12,14],cashkt:16,cashsigningpubkei:11,cashstat:11,caus:[1,16],center:16,certain:[1,6,16],certainti:2,cev:4,chain:[2,3,10,11,16],challeng:3,chanc:[1,11],chang:[0,1,2,3,7,8,10,11,12,13,15,16,17,18],channel:11,charact:1,charg:10,check:[1,2,4,5,6,10,11],checkabl:10,checkdepend:11,checksufficientsignatur:11,chf:15,child:11,children:11,childrenfor:11,choic:[1,2,3],choos:[2,4,16],chosen:[2,3],chunk:18,circl:17,claim:[3,6,16],clean:11,clear:[11,15],clearer:[8,11],clearli:1,click:[4,17],client:[9,10],clock:[10,14],clone:[1,4],close:10,closer:2,closur:1,cloud:9,cluster:2,cmd:16,coars:3,code:0,codebas:[1,16],cognit:3,coin:3,colleagu:1,collect:[1,9],collector:[1,9,11],colour:14,column:9,com:[0,4,12],combin:[3,5,16],come:[3,6,11,13],command:[0,2,3,4,5,7,9,10,11,14,15],commanddata:10,commerci:[5,6,10,11,12,14],commercial_pap:16,commercialpap:[6,16,17],commercialpapertest:[16,17],commit:[2,11,13],committedst:2,commod:15,common:[3,7,11,15,16],commonleg:7,commonli:16,commun:4,compani:10,companion:[11,16],compar:[3,8],compat:13,compel:2,compil:[14,16],complet:[3,8,11,14,16],complex:[1,3,15,16],complic:[11,16],compon:8,compos:[11,15,16],compris:7,comput:[7,10,11],concept:[2,3,10,11,16],conceptu:11,concern:[3,11,16],conclus:[3,10],concurrenthashmap:1,condit:[2,10,11],config:9,configur:[4,9,11,14],confirm:[2,4,8],conflict:[2,3,5],confus:11,connect:[6,9,16],consid:[1,3,7,10,13,16],consist:[3,6,7,11],constant:[1,16],constantli:10,constraint:10,construct:[1,8,10,11,16,18],constructor:[10,16],consult:10,consum:[2,3],consumingtx:2,consumpt:10,contact:[4,11],contain:[2,3,7,8,9,10,11,13,14,15,16,18],content:[1,3,4,8,9,10,16],context:[1,3,9,10,15],continu:[5,7],contract:[2,3,5],contractst:[2,15,16,17],contractstateref:16,contrast:[3,10,11],control:[1,2,3,4,9,11,16,18],conveni:[1,3,16],convent:[7,11],convers:15,convert:[7,15,16],convinc:11,copi:[1,3,8,11,16,18],copyonwritearraylist:1,copyright:1,corda:[2,3,4],core:[8,15,16],corner:4,correct:[3,13,16],correctli:[3,10,16],correspond:16,correspondingli:1,cost:[10,16],could:[1,2,3,10,11,15,16],count:7,countabl:12,counter:[1,11],counterparti:7,countri:[10,15],coupl:[10,11],cours:[9,10,16,18],cover:[2,3,10,11,15,16,18],cp_program_id:16,creat:[1,2,3,5],createdummyir:7,createmessag:8,creation:[3,5,7,16],creator:10,crisp:16,critic:[3,13],crop:3,curl:9,currenc:[6,7,12,15,16],current:[1,2,3,6,7,8,10,11,13,15,16,17],currentwallet:11,curv:[6,7],custom:[2,9,14],customis:18,cut:5,cycl:1,dai:[7,9,10,13,15,16,17],dashboard:9,data:[0,1,2],databas:[3,6,11],dataset:7,date:[5,7,9,10,13,14],daterollconvent:15,deadlin:15,deal:[1,10,14,15],dealstat:15,debug:11,decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9:9,decd:9,decentralis:10,decid:[4,10,16],decis:3,declar:[1,8,16],dedic:1,defin:[1,2,3,6,8,9,10,11,15,16,17,18],definit:[11,15,16],delai:[7,10],delet:[1,3,11,16],deliber:3,deliv:[8,15],deliveri:[8,11,14,16],demand:[3,15],demo:[5,6,13],demonstr:[14,18],denial:2,denomin:6,dens:1,depend:[1,3,4,10,11,16],dependencytxid:11,deposit:[6,16],depth:16,deregist:8,deriv:[7,11,16],describ:[1,2,3,5,11,15,16],descript:1,deserv:13,design:[1,3,5,6,10,16,18],desir:[11,15,16],desktop:9,despit:[11,16],destin:8,destroi:[3,16],destroypaperatredempt:[16,17],destructur:16,detail:[1,2,3,5,6],detect:1,determin:7,develop:[1,3,6,8,11,13,14,16],devic:3,devis:3,diagram:[7,17],diamond:17,didn:[1,11,13,14,16],differ:[1,3,6,7,10,11,15,16],difficult:[8,11],digest:2,digit:[3,10,11,16],digitalsignatur:[2,10,11],direct:1,directli:[1,9,15],directori:[0,14,16,18],directthreadexecutor:1,dirti:16,disadvantag:3,discov:3,discuss:[3,8,15],disk:[11,15],disobei:10,disprov:5,disput:[2,7,16],disrupt:8,distinguish:16,distribut:[2,3,5,6,10,11],distrust:[2,11],divid:2,dlg:11,doc:[0,1,16],docker:9,docsit:[0,13],doe:[1,2,3,6,7,8,9,10,11,16,18],doesn:[1,2,3,4,8,9,10,11,14,16],dokka:0,dollar:[16,17],domain:[16,17],don:[1,3,4,6,8,11,13,16],done:[0,3,11,16],dot:7,doubl:[3,14,16],doubt:[1,6],down:[1,3,10,16],download:[4,5],downsid:[1,3],drag:17,drive:[3,18],driven:14,driver:18,drm:10,dsl:[16,17],due:[1,3,6,7,10,11,16],dummi:16,dummy_pubkey_1:16,duplic:16,durat:[10,16],dure:[1,7],dynam:[16,18],each:[1,2,3,6,7,8,10,11,12,13,16,18],earli:[1,16,17,18],earliest:7,eas:8,easi:[1,3,6,10,16],easier:[1,11,16],easiest:16,easili:[1,10,11,14],econom:7,edit:4,editor:4,effect:[3,7],either:[1,2,3,6,7,10,11,16,18],element:[1,3],ellipt:6,els:[2,3,16],emb:16,embed:[3,6,9,10],emit:16,empti:16,enabl:16,encapsul:[1,15],encod:10,encount:6,end:[1,6,7,10,11,13,18],endpoint:9,enforc:[1,3,16],engin:16,english:[1,16],enorm:11,enough:[1,4,8,11,16,18],ensur:[1,2,3,4,8,11,13,15,16],enter:[16,18],entir:[2,3,7,8,10,16],entireti:7,entiti:[2,3,10,16],entri:[3,7,11,16],enumer:7,environ:[1,10,11],envisag:16,equal:[2,11,16],equival:[1,7,15,16],especi:[15,17],essenti:[9,10,15,16],establish:14,etc:[1,7,10,11,12,13,15,16],euribor:[9,10],evalu:[7,10],even:[3,6,8,10,11,16],event:[1,2,3,7,10,11,14,15],eventu:13,ever:[1,3],everi:[2,3,10,11,13,16,18],everybodi:[3,10],everyon:10,everyth:[2,8,16,18],evid:10,evolut:3,evolv:[16,18],exact:[10,16],exactli:[3,8,16],examin:[1,3,10,16],exampl:[0,1,2,3,7,8,10,11,15,16,17,18],excel:10,except:[1,11,16],excess:1,exchang:[7,11,15,16],execut:[3,10,15,16],executor:[1,8],exercis:16,exist:[2,3,5,7,16,18],exit:16,expect:[1,6,8,11,13,16],expectedtypenam:11,expectfailureoftx:16,expens:1,experi:[3,13,18],experiment:11,explain:[1,8,11,12],explan:1,explicit:[1,3,10,11],explicitli:[1,3,16],explor:[1,3,4,5,6,9,16,18],exploratori:8,expos:[1,2,8,9,10,11,15],exposur:7,express:[3,6,7,10,11,16],extend:[1,2,6,15,16],extens:[1,15,16],extent:3,extern:[6,11,18],extract:[3,9,10,11,15,16],extrem:[3,10,16],face:[6,16,17],facevalu:16,fact:[1,2,3,7,10,11,16],factor:[3,7],fail:[8,16],failur:[11,16],fairli:[1,11],fake:[6,14,16,18],fals:[1,8,10,11,16],familiar:[3,16],far:[11,14,16],fashion:1,fast:[3,8,14],fault:11,featur:[1,11,13,16,17],feed:10,feel:[16,18],fetch:[8,9,10],few:[1,6,8,9,10,11,13,14,16],fiber:11,field:[1,7,10,11,16,17],file:[0,1,3,8,9,11,14,15,16,18],fill:[1,11,16],filter:1,filterisinst:16,finalis:[7,11],financ:[11,18],financi:[3,5,11],find:[0,3,9,11,14],fine:3,finish:[8,11],firm:16,first:[1,2,4,7,8,9,10,11,12,14,15,16,18],firstli:16,fit:[1,3],fix:[1,3,5,6,7,8],fixabledealst:15,fixedleg:7,fixedlegpaymentschedul:7,fixedratepaymentev:7,fixof:10,flag:[9,18],flexibl:3,flight:3,floatingleg:7,floatinglegpaymentschedul:7,floatingratepaymentev:7,flow:[1,7,16],flux:18,fly:11,fold:1,folder:0,follow:[0,1,2,3,4,5,8,9,10,11,15,16,17],font:1,foo:[1,8],foobrokenexcept:1,fooutil:16,forc:[3,9],fordai:10,forev:13,forget:[11,16],form:[2,3,11,16],formal:[8,16],format:[0,1,3,9],forth:11,forward:[8,10,11,13,14],found:[4,9,10,11,13,18],four:16,frame:[1,11],framework:[3,5,6],free:[3,10,11],freeform:16,freeli:10,frequenc:7,frequent:11,fresh:[10,16],freshkei:11,freshli:16,from:[0,1,2,3,4,6,7,8,9,10,11,12,13,15,16,17,18],front:16,frustrat:3,full:[1,8,11,16],fulli:[1,3,8,11,16],fullysign:11,fun:[2,10,11,16],fund:3,fundament:[2,3,5,16],fungibl:[6,15,16],fungibleasset:[5,12],funni:11,further:[3,6,7,15],futur:[2,3,10,11,15,16,17,18],gain:6,game:11,garbag:[1,9,11],gather:16,gavin:3,gbp:15,gcd:3,gear:13,gener:0,generateirsandfixsom:7,generateissu:16,generatemov:16,generateredeem:16,generatespend:[11,16],genuin:1,get:[1,2,3],getbloomfilters:1,getclass:16,getcommand:16,getfacevalu:16,getfix:7,getinput:16,getissu:16,getkei:16,getlegalcontractrefer:16,getmaturityd:16,getnotarysignatur:2,getoutput:16,getown:16,getprogramref:16,getprotocoltrack:11,getsign:16,getter:16,gettim:16,getvalu:16,git:[4,12,13],github:0,give:[2,3,16],given:[2,3,8,10,11,16],givenpric:11,global:[1,3,10],glue:11,gnu:0,goal:[1,3,5,6,11,13],goe:14,gone:[11,16],good:[1,4,11,16,17,18],got:[9,11],gover:16,grade:15,gradl:[4,6],gradlew:[4,14],grammar:1,granular:3,graph:[3,6,9,11,16,17],graphit:9,greatest:3,green:4,groom:3,group:[3,5,8],groupstat:16,guarante:13,guava:[1,6],gui:11,hack:3,had:[2,16],hand:[11,16],handl:[1,2,3,8,11,16],handler:[8,11],happen:[1,2,3,10,11,13,16],happi:14,hard:[1,3,11,13],harder:[3,16],hase:7,hash:[2,3,6,9,10,11,15,16],hashcod:16,hashmap:2,hasn:4,hassl:11,hat:13,have:[1,2,3,4,6,7,8,10,11,12,13,14,16,18],haven:[12,16],heap:11,hearn:3,heart:16,heavi:13,heavili:3,hedg:7,heirarchi:1,held:16,hell:11,hello:11,help:[1,3,8,11],helper:[7,8,16],henc:[2,3,7],her:[16,17],here:[1,3,6,8,9,10,11,12,15,16,17,18],hierarch:11,hierarchi:11,high:[3,10,11],higher:[1,2,4,16],highlight:16,histori:[2,11],hit:[3,4],hold:[3,8],holder:[1,3,16],holidai:[7,10,15],home:4,hood:11,hopefulli:18,hotspot:1,how:[1,3,5,6,8,10,11,12,13,14,15],howev:[2,3,7,8,10,11,15,16],html:[0,1],http:[0,4,9,10,14,16,18],hub:11,human:[3,10,11],hundr:11,hurt:11,hypothesi:5,idea:[1,3,4,6,11,16,18],ideal:[11,16],ident:[2,3,10,11,14,15,16],identifi:[3,6,7,8,9,10,11,15],identityless:3,identityservic:11,ignor:16,illeg:10,illegalargumentexcept:[1,10,11,16],illegalstateexcept:[1,16],illustr:1,imagin:[1,11,16],immedi:[3,16],immut:[1,3,7,10,16],imper:1,implement:1,impli:11,implic:[2,3],implicitli:7,impos:[10,11,16],imposs:[3,10],improv:[3,13,16,17],inbackground:8,includ:[1,3,4,5],incorpor:10,increas:[1,8],indent:1,independ:[2,10],index:[3,4,7,16],indic:[1,7,8,11,16],individu:[1,8,16],industri:[5,6,9],infer:16,infix:16,influenc:9,info:11,inform:[1,2,3,11,12,15,16],infrastructur:[3,9],inher:3,inherit:[1,8,16],init:10,initi:[2,8,11,12,16,18],inmemorymessagingtest:8,inmemoryuniquenessprovid:2,inoutgroup:16,input:[2,3,10,11,15,16,17],inputindex:2,insert:[1,8,9,10],insid:[3,8,11,14,16],instal:[0,4,14],installdist:14,instanc:[1,3,5],instant:[1,10,11,16],instanti:[3,11],instead:[1,3,6,16,18],institut:[3,6],institutionrefer:16,instruct:[9,16],instrument:7,insuffici:3,insufficientbalanceexcept:16,integ:16,integr:[1,2,6,10,11,17],intellig:1,intend:[1,3,6,9,10,11,15],intent:[10,16,17],intention:1,interact:[1,3,10,11],interchang:15,interest:[5,6],interestrateswap:6,interfac:[1,2,5,6],intern:[6,8,16],internalis:1,interop:[6,16],interpret:[1,3,16],intersect:16,interv:15,introduc:[1,2,10,15,16],introduct:[5,6],intuit:1,invalid:[2,10,11,16],invari:16,investig:11,invoc:8,invok:[1,3,8,9,11,16],involv:[2,3,8,10,11,15,16,18],iou:6,ipsa:10,irsdemo:14,irsexport:7,irstest:7,irsutil:7,isaft:16,isempti:16,isinst:11,isn:[1,11,16,18],issu:[2,3,6,8,10,13,15,16,17,18],issuanc:[11,15,16,17],issuer:[3,16],item:16,iter:[11,13,16],itself:[2,3,7,8,9,10,11,16],jar:[0,3,9],jarinputstream:3,java:[1,3,6,8,9,11,16,18],javaclass:11,javacommercialpap:16,javadoc:1,jdk1:4,jdk:[4,11,16],jetbrain:[4,6],jira:6,jmx2graphit:9,jmx:9,jmxtran:9,job:18,join:[8,16],joint:16,jolokia:9,json:[9,18],judgement:1,jump:14,junit:[6,16],just:[1,3,4,8,9,11,16,18],justifi:5,jvm:[3,6,9,11,18],kafka:8,kdoc:1,keep:[3,11,16,17],kei:[1,3,6,8,10,11,14,15,16],kept:11,key_mismatch_at_issu:16,keymanagementservic:11,keypair:[11,16],keyword:[1,16],kick:11,kind:[3,6,8,10,11,16,18],know:[2,3,6,10,11,14],knowledg:10,known:[3,5,7],kotin:16,kotlin:[0,1,4,5],kryo:[6,8,11],label:[11,16,17],labori:16,lack:3,land:7,languag:[1,3,4,5,6,16,17,18],larg:[3,10,11,15,16,18],larger:[1,3],last:13,latenc:[2,10],later:[1,3,6,8,10,11,15,16],latest:[1,4],latter:[1,16],layer:[3,6,8,11],layout:17,lead:[1,3,16],leak:[2,3,11],learn:[3,5,11,14,16,18],least:[10,16],leav:[1,11],ledger:[3,5,7,9,10,11,16,17],ledgertransact:15,left:[8,11],leg:[6,7],legal:[2,3,10,15,16],legalcontractrefer:16,legallyidentifi:[2,10,11],legallyidentifiablenod:11,less:[11,16,17],let:[1,3,9,10,11,14,16],letter:1,level:[1,4,7,8,10,11,16],lib:0,liber:1,libor:[7,9,10],librari:[1,6,9,10,11,15,16],licens:1,life:18,lifecycl:5,lifetim:7,like:[1,2,3,4,7,8,9,10,11,13,15,16,18],likewis:16,limit:[3,5,16],line:0,linearst:15,link:[1,3,10,11,15,16],linkabl:3,linux:9,list:[0,3,8,10,11,13,14,15,16],listen:[1,6],listenablefutur:11,liter:3,littl:[1,16],live:7,livelock:3,load:[2,3,14,15,16,18],loan:[7,10],local:[0,3,4,9,10,11],locald:10,localhost:9,locat:[14,15,16],lock:[1,16],log:[11,14],logger:11,logic:[2,3,6,8,11,16,18],longer:[1,7,10,11],look:[1,7,8,9,10,11,13,16,18],loop:[1,7,16],loquitur:10,loss:10,lot:[1,3,7,14,18],low:[2,11],lower:[1,10],lurch:11,mac:9,machin:[3,5,8,10],maco:14,made:[1,3,5,7,11,12,13],mai:[1,3,6,8,9,10,11,13,16,18],mail:[13,14],main:[11,16,17,18],maintain:[2,3],maintan:10,mainten:8,major:13,make:[0,1,2,3,7,8,10,11,13,14,16],makenod:8,maker:6,malici:11,manag:[3,5,9],mani:[1,3,6,8,10,11,15,16],manipul:15,manner:11,manual:8,map:[1,2,5,7],mappabl:16,mark:[1,11,16],markdown:1,marker:[11,16],market:5,master:12,match:[3,8,10,11,16],matter:16,matur:[7,9,10,16],maturityd:16,maven:4,maximis:3,maximum:3,maybestx:11,maybetraderequest:11,mbean:9,mean:[1,3,8,10,11,15],meaning:2,measur:[7,16],mechan:[12,16],meet:16,mega_corp:16,mega_corp_kei:16,mega_corp_pubkei:17,megacorp:[16,17],member:7,memori:[2,5],menlo:1,mention:11,menu:4,mere:[7,16],merg:[3,6,12,15,16],mess:11,messag:[1,3,5,6],messagehandlerregistr:8,messagerecipi:8,messagerecipientgroup:8,messagingservic:[8,11],method:[1,5,8,9],metric:9,middl:[1,8,11],might:[1,3,4,7,11,16],mike:3,mileston:5,mind:[1,10,11,16],mine:3,minim:[3,11],minimis:[2,3,8],minimum:[3,7],minor:13,minu:16,minut:[6,10],misc:8,miss:[1,11,16,18],missingsig:11,mission:9,mix:[1,11,16],mock:8,mode:[6,8],model:1,modest:3,modif:16,modifi:[2,4,7,11,15,16],modul:[8,16],moment:8,monei:[10,16],monetari:16,monitor:[1,5],month:[7,11,13],more:[1,2,3,6,7,8,9,10,11,12,14,15,16],moreexecutor:1,most:[3,7,8,9,10,11,16],mostli:16,move:[11,12,13,16,17],movement:[11,16],much:[1,3,6,11,12,16,18],multi:[1,11,16],multipli:7,must:[2,3,8,9,10,11,16,18],mutabl:[1,3,16],mutat:3,mutual:[2,11],myfil:9,mykeypair:11,nail:1,namedbyhash:15,namespac:11,narrow:1,nativ:11,natur:16,naval:[3,10],navistar:10,necessari:[1,2,13,14],need:[0,1,2,3,5,7,8,9,11,13,14,15,16,18],negoti:[3,15],neither:[11,16],nest:11,net:[7,16,17],network:[2,3,5,6],neutral:6,never:[1,3,10,16],newli:11,newown:16,next:[1,4,7,11,16],nice:14,nio:1,noddi:9,node:[3,5,6,8],nodea:14,nodeb:14,nodeinterestr:10,nodeservic:10,non:[0,1,3,5,11,12,14,15],none:11,normal:[7,11,15,16],not_matured_at_redempt:16,notaris:2,notaryexcept:2,notaryprotocol:2,notat:11,note:[0,1,3,5,7,11],noth:[1,3,16],notic:[1,16],notif:8,notifi:8,notion:[3,6,7,16],notnul:16,now:[1,3,4,8,10,11,12,14,16,17,18],nugget:16,nullpublickei:16,number:[1,3,7,8,10,11,13,14,15,16],numer:3,obj:16,object:[1,3,6,7,8,9,10,11,15,16,17,18],oblig:[7,15],observ:[3,7,10,11],observatori:[3,10],obsolet:6,obtain:[1,2,17],obviou:[1,3,10],obvious:[7,16],occasion:5,occur:[2,10,11,16],occurr:10,odd:[11,16],off:[8,11,16,17],offer:11,offlin:8,offset:7,often:[1,3,7,10,11,16],oftenor:10,oil:12,onc:[0,1,2,6,7,8,10,11,13,15,16,18],onli:[1,2,3,6,7,8,9,10,11,16,17,18],onto:[1,11,16,17],opaqu:[6,8],opaquebyt:16,open:[2,3,4,10,11,14,17],openjdk:4,oper:[7,8,9,10,11,16],optim:1,option:[0,7,8,10,11,16,18],oracl:[3,4,5,6,7,8,9],orchestr:[5,12,18],ordain:7,order:[0,1,2,3,6,7,8,11,15,16,17],ordinari:[3,6,11,16],org:[0,4,16],orient:5,origin:[15,16],otc:6,other:[1,2,3,6,7,8,10,11,14,15,16],othersid:11,otherwis:[11,16],our:[1,3,11,13,16],ourselv:[11,16,18],oursignatur:11,out:[1,2,3,4,6,9,10,11,16],outag:8,outcom:11,outlin:[3,11],outpoint:3,output:[2,3,10,11,14,15,16,17],outsid:[3,8,10,11,16,18],outstat:16,over:[1,2,3,7,8,9,10,11,15,16],overal:[2,8],overflow:1,overload:11,overnight:15,overrid:[2,11,16],overwhelm:3,own:[1,8,9,10,11,13,16,17,18],ownablest:[11,15],owned_bi:16,owner:[11,15,16],ownership:[11,16],owningkei:[11,16],p2p:[6,11],pack:16,packet:3,page:[4,10,16],pai:[10,11,16,17],paid:[3,7],pair:[3,11,16],paper:[5,6,11,12,14],paper_1:[16,17],parallel:[3,8,11],parallelis:3,paramet:[1,11,14,16],parameteris:3,parent:11,pars:[10,18],part:[1,2,3,10,11,15,16,18],parti:[1,2,3,5,6,7,8,10],partial:[2,11,16],partialtx:11,particip:[3,16,18],particular:[1,2,3,9,11],partyandrefer:1,partyrefer:[1,16],pascal:1,pass:[2,8,11,16,17],past:[1,10,14,16,18],patch:1,path:[1,9,16],pattern:[1,3,16],paye:3,payer:[3,7],payment:[3,7,10,11,14,16,17],pdf:10,peer:[6,8,10,11],penni:16,peopl:[1,3,6,16],per:[1,3,18],perform:[1,2,3,7,10,11,14,16],perhap:[3,16],period:7,perman:[6,16],persist:[6,8,11],perspect:[3,11,16],phrase:10,physic:[2,10],pick:[8,11,13,16,18],piec:[1,2,3,8,11,16],ping:8,pip:0,pki:3,place:[0,1,3,6,7,8,10,11,13,15,16,18],plai:11,plan:[8,14],platform:[2,3,5,6,7,8,10,11,16],pleas:[1,3,4,16],pluggabl:12,plugin:[4,9],point:[1,2,3,9,10,11,13,16],pointer:[2,11],pointless:1,pong:8,pool:[1,3,11],poor:3,pop:[4,8],popular:6,popup:4,port:13,posess:11,posit:[1,2,3,11],possibl:[3,8,10,11,16],potenti:[1,2,6,11,16],pound:16,power:[3,5],practic:[3,16],pre:[0,3,7,11,16,18],preced:16,precis:[3,6,10],precondit:1,prefer:[1,3],prefix:11,preliminari:8,prepar:[3,16],present:[2,5,7,10,15,16],preserv:[2,3],press:16,pretend:9,pretti:[3,11,16],prevent:16,previou:[3,15],previous:[7,10],price:[3,10,11],primari:[6,10],primit:16,print:14,priv:11,privaci:[1,2,3,11,16],privat:[2,3,11,16,18],probabl:[4,10,16,18],problem:[2,3,10,11],proce:11,procedur:11,process:[2,3,5,7,8,9],processor:3,produc:[0,16,17],product:[1,5,6,13,15,16],profit:[16,17],profound:3,program:[1,3,6,8,9,11,14,16,18],programref:16,progress:[2,5,7],progresstrack:11,project:[4,14],proof:[3,5],propag:[5,9,16],properli:11,properti:[1,9,11,16],propos:[5,11],prose:[10,15],protect:11,protocol:[2,3,5,6,8,9,10],protocollog:11,protocolstatemachin:11,protocoltrack:11,prototyp:[1,3,5,6,10,16],prove:[2,3,5,16],provid:[0,1,2,3,7,8,9,10,11,15,16,18],provision:15,pseudo:10,ptx:11,publickei:[5,11],publicli:5,pull:4,pump:8,punish:10,purchas:[11,14],pure:[3,10],purpos:[6,11,16],push:13,put:[1,11,13,16,18],python:0,qualiti:5,quantiti:[3,6,16],quasar:11,queri:[7,10],question:[1,4,10],queu:8,queue:[1,6,8,11],quick:10,quickli:[3,8,16],quit:[1,10,11,16],r3corda:12,r3dlg:13,r3prototyp:[0,4,14],r3repositori:4,rais:2,random63bitvalu:11,random:[3,11],rang:10,rapid:[1,6,13],rate:[1,5,6],ratefixprotocol:10,rather:[1,3,11,16],raw:[9,11],reach:[2,3,7,10],reachabl:11,read:[1,3,5,6,9,10,11,16,18],readabl:[6,11],reader:16,readi:[13,16],readili:15,readm:1,real:[1,6,8,10,16,18],realis:11,realism:8,realiti:7,realli:[1,2,3,11,16],reason:[1,3,7,11,15,16],reassign:16,recal:7,receiv:[3,7,8,10,11,13,16,17],receiveandcheckproposedtransact:11,receiveandvalidatetraderequest:11,recipi:[3,8,16],recognis:[3,10,16],recommend:[1,8,18],record:8,recov:8,recreat:11,red:[4,7],redeem:[6,16,17],redempt:[16,17],redemptiontim:[16,17],reduc:1,redund:1,ref:[11,16],refactor:12,refer:[1,2,3,6,7,10,11,15,16],referenc:2,refin:6,reflect:16,refus:4,regard:2,regardless:11,regener:[7,13],regist:[1,8,9,11,18],registr:8,regular:[6,9,11,16],reissuanc:[3,16],reject:16,rel:[3,8],relabelablestep:11,relat:[7,16],relationship:16,releas:5,relev:[3,15],reli:3,reliabl:8,relianc:3,relic:9,religi:1,remain:[16,17],remeb:4,rememb:[1,4,11,16],remind:11,remot:4,remov:[8,11,16],render:[1,11,17],repeat:[1,7,8,11],replac:[2,4,7,9,13,15,16],replic:3,repoint:2,report:8,repositori:[1,4],repres:[1,3,7,8,10,11,15,16],represent:7,request:[2,3,8,10,11],requestingparti:2,requiresinglecommand:16,requirethat:16,resel:10,reserv:11,reset:7,reshap:3,resolut:[2,3,5,11],resolv:[11,15],resolvetransactionsprotocol:11,resourc:11,respect:[1,3,11,14,16],respend:3,respons:[2,3,8,10,11],rest:[2,3,8,9,11,18],restart:[4,11,14],restor:11,restructuredtext:0,result:[1,2,3,7,10,11,16],resultfutur:11,resum:11,resurrect:11,retain:8,retri:[8,11],retriev:7,reus:[3,11],reusabl:10,reveal:[2,3,11,16],revers:11,review:[1,13],revis:7,rewrit:11,right:[1,4,8,9,11,13,18],rigid:3,rigidli:1,risk:11,role:[14,18],roll:[7,11,14],rollov:[15,16],root:[14,16,17],roughli:[10,13],rout:11,router:8,rule:[1,10,11,16],run:[0,1,2,3,4,5,6,8,9,11,13],runbuy:11,runnetwork:8,runsel:11,runtim:[1,11],safe:[1,3,11,16],safeti:1,sai:[1,2,3,16],sale:[14,16],same:[1,2,3,6,7,8,10,11,14,16,17],sandbox:[3,6,16],saniti:11,satisfi:16,save:[1,16],scala:[6,16],scalabl:[1,3],scale:7,scenario:[3,18],scene:[11,16],schedul:[7,9],scope:[3,16],scrape:9,scratch:18,screen:[1,4],script:[0,3,16],scroll:14,scrub:11,seamless:6,search:[4,11,16],second:[7,11,14,16],secondari:11,secp256r1:6,section:[3,13,16],secur:[3,8,11],securehash:[2,16],see:[0,1,2,6,7,8,10,11,14,15,16,18],seed:11,seek:3,seem:3,seen:[1,7,10,11,16,17],select:[4,16],self:6,sell:[6,11,16,18],seller:5,sellerownerkei:11,sellersig:11,sellertradeinfo:11,semi:[3,10],send:[1,3,8,9,10,11,13,16],sendandrec:11,sender:3,sendsignatur:11,sens:[7,10,11,16],sent:[8,11,16],separ:[2,3,9,10,11,14,15,16],sequenc:[3,8],sequenti:[8,11],seri:11,serial:[6,8,16],serialis:[1,3,6,8,11,16],serializablewithkryo:16,serializeablewithkryo:16,seriou:[3,13],serious:18,server:[9,10,18],servic:5,servicehub:11,session:[8,11],sessionid:11,set:3,setof:11,setter:16,settim:11,settl:[8,10,15],settlement:11,setupa:14,setupb:14,sever:[3,11,16,18],sha256:16,sha256sum:9,sha:[3,9],shape:3,share:[3,7,10,11,16,18],shasum:9,she:16,shortcut:6,shorthand:16,shot:8,should:[1,2,3,4,6,8,11,14,15,16,18],shoulder:1,shouldn:[11,16],show:[3,4,6,14,16,17],shown:[11,16],shutdown:11,side:[10,11],sig:16,sign:[2,3,6,7,8,10,11,15,16],signatur:[2,3,6,8,10,11,15,16],signatureexcept:11,signaturesfromsel:11,signedtransact:[11,15,16],signer:[10,16],signific:3,significantli:7,signoff:10,signwith:[11,16],signwithecdsa:11,signwithourkei:11,silver:1,similar:[1,3,8,10,16],simpl:[1,3,6,7,8,9,11,16,17],simpler:[3,6],simplest:[3,11,16,18],simpli:[1,3,8,11,15,16],simplifi:[1,3,6,8,15,16,18],simultan:[3,8,11,16],singl:[1,2,3,9,10,11,16,17,18],singlemessagerecipi:[8,11],singleton:[11,16],sit:8,site:[1,13],situat:[1,3],size:[1,3,7,11,16],skip:11,slight:16,slightli:16,slip:13,slow:[1,3],slowest:3,small:[3,6,10,11,14,16,17],smart:[5,6,10,12],smm:11,smooth:16,snapshot:[3,12,13],snide:0,snippet:[2,11,16],softwar:[6,11,13,18],sold:[11,16,17],solv:[3,10,11],solvenc:10,some:[1,2,3,6,8,9,10,11,12,14,15,16,17,18],somed:16,someon:[2,3,8,16],someprofit:[16,17],someth:[1,3,4,7,14,15,16,18],sometim:[3,8,9,10,11,16],somewhat:[3,11],somewher:[16,17],sophist:3,sort:[10,11],sound:[1,11,16,17],sourc:[4,7,10,11],sparingli:1,special:[2,3],specialis:11,specif:[2,3,8,9,10,11,15,16,17],specifi:[0,1,2,3,6,8,10,11,16,18],speed:[3,11],spend:[3,11,16],spent:3,sphinx:0,sphinx_rtd_them:0,split:[3,6,12,15,16],spread:[2,8,11],spreadsheet:10,squar:17,src:[16,17,18],stabilis:13,stabl:13,stack:11,stage:[1,11,16,18],stai:[3,16],stake:3,standalon:[6,10],standard:[1,5,6,9,11,15,16],standardis:[3,15,16],start:[1,3,5,7,8,9,11,14],state:[2,3,5,6,7,8,10],stateandref:[11,15,16],statehistori:2,stateless:3,statemachinemanag:11,statement:[1,3,10,11,16],stateref:[2,3,15],statesoftyp:11,statist:9,status:3,step:[5,10,11],still:[2,3,11,16,18],stock:[3,10],stop:[1,8,11],storag:3,store:[2,11,15,16],stori:1,straightforward:[11,16],stream:11,stress:1,strictli:[3,7],string:[8,10,11,16],strong:6,structur:[1,3,4,6,10,11,16],studi:16,stuff:[1,11],stx:11,sub:11,subclass:[11,15],subgroup:3,submiss:10,submit:[1,2,8,11],subprotocol:[2,11],subscrib:8,subtask:11,subtl:[1,3],successor:[2,6],sudo:0,suffer:3,suffic:10,suffici:[3,5,8,10,13],suffix:16,suggest:[8,16],suitabl:[8,13],sum:16,sumcashbi:[11,16],sumcashornul:16,summari:[12,13],summaris:3,sun:1,superclass:[11,12,15],superior:1,supersed:3,supertyp:16,suppli:14,support:[1,3,5,6,7,8,10,11,12],suppos:[11,16],sure:[2,13,14,16,18],surfac:11,surround:[1,16],surviv:11,suspend:5,swap:[5,6],swapsignatureswithsel:11,symbol:4,synchronis:[1,3,10],syntax:[6,16],system:[2,3,6,9,10,11,14,16],tab:[1,4],tag:[1,13],tailor:5,take:[1,6,7,11,15,16,17],tamper:11,target:[0,1,3,6,9],targetrecipi:8,task:[3,11],team:4,technic:5,techniqu:[1,3,10,16],tell:[0,8,11],templat:15,tempor:10,temporari:3,temporarili:[11,13],tempt:16,temptat:11,ten:16,tenor:[7,9,10,15],term:[3,15,16],termin:[7,9,11,14],terminolog:3,test:[0,4,5,6,8,11,13],test_tx_tim:16,testutil:16,testwithinmemorynetwork:8,text:[1,4,9],than:[1,2,3,5,9,11,16,17],thei:[1,3,6,7,8,9,10,11,13,14,15,16],theirsessionid:11,them:[1,3,4,6,7,8,9,11,13,14,15,16,18],themselv:[8,10,11,15,16],theori:[5,10],therefor:[3,4,6,11,13,16],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18],thing:[1,3,6,10,11,14,15,16,18],think:[1,3,4,11,16],third:[3,14,16],those:[3,8,9,10,11,15,16],though:[8,9,11,16],thought:[3,6],threadsaf:1,three:[14,15,16],threshold:16,through:[3,7,9,11,16,18],throughput:[2,3],throwifsignaturesaremiss:11,thrown:16,thu:[1,2,3,9,10,16],tighten:16,tightli:11,time:[1,2,3,6,7,9,10,11,15,16,17],timelin:16,timestamp:1,timestampauthoritysig:11,timestampcommand:10,timestampercli:16,timestamperservic:10,timestampingauthor:11,timestampingprotocol:11,titl:4,todo:[1,11,16],togeth:[3,11,16],token:15,told:1,toledgertransact:11,toler:[2,10],too:[1,11,16,17],took:11,tool:[6,9],toolbar:4,top:[1,3,4,11,16],topic:[8,11,18],topriv:11,toset:11,tosignedtransact:[11,16],tostr:[1,11,16],total:[3,16],toward:13,trace:11,track:[3,5,8],tracker:[6,11],trade1:14,trade:[5,6,7,10],trade_top:11,tradeoff:1,trader:5,traderdemo:18,traderequest:11,tradit:[3,16],traffic:[3,11],transact:[2,3,5,9,10,11],transactionbuild:[11,16],transactionforverif:16,transactiongroup:16,transactiongroupdsl:17,transactiongroupfor:17,transactiongroupfortest:16,transfer:16,transit:[5,16,18],treat:16,tree:11,tri:[3,16],tricki:[3,11],trigger:[10,14],trivial:[1,3],trust:[3,11],truth:11,tsa:[3,11],tsasig:11,tupl:1,ture:3,turn:[3,11,15,16,18],tutori:[5,6,10,11,12,16,18],twice:6,two:[1,2,3,5,6,7,8],twopartytradeprotocol:11,txbit:11,txhash:[3,11,16],txt:9,type:[1,2,3,5,7,10,11,12],typenam:11,typetobui:11,typic:[3,8,9,11,15,16,18],unacceptablepriceexcept:11,under:[0,11,13,16,18],underli:[3,7,11,15],underscor:16,understand:[3,8,9,16,17,18],unexecut:16,unexpect:11,unfinish:11,unfortun:[11,16],unguess:11,unifi:18,unindex:4,uniqu:[2,3,10,11],uniquenessprovid:2,unit:[2,3,4,6,8,11,16,17,18],unix:[9,14],unknow:10,unless:[1,10,11,13,16,18],unlik:[4,16],unnatur:3,unnecessari:16,unpack:[11,16],unread:11,unrecognis:16,unrel:16,unreleas:5,unserialis:11,unset:7,unspent:3,unstart:11,unsupportedoperationexcept:16,until:[2,3,7,8,11,13,18],untrustworthydata:11,unus:8,unusu:16,updat:[3,4,8,11,13,16],upgrad:[4,5],upload:5,upon:[7,11,16],url:4,usabl:[6,13],usag:1,usd:15,useless:16,user:[0,1,3,4,6,8,10,11],usr:0,usual:[3,13],util:[6,8,16],vagu:1,val:[2,8,10,11,16,17],valu:[3,6,7,10,16,17],valuabl:10,valuat:7,vanilla:[6,7],vari:5,variabl:[1,3,7,11,16],variant:16,variou:[1,3,6,9,11,16],vehicl:3,vendor:[6,9],verbos:16,veri:[1,3,6,10,17,18],verif:[3,6],verifi:[2,3,5,6,8,10,11,15],verifytransact:11,versa:[7,11,15],version:[4,6,7,8,11,12,13,15,16],versu:11,vertic:1,via:[0,1,3,7,9,10,11,14,18],vice:[7,11,15],view:[1,7],virtual:[3,5],visibl:[2,3],visualis:5,vital:11,wai:[1,3,6,9,10,11,16,18],wait:[4,8,11,14],wallet:[3,11,16],walletservic:11,want:[1,3,4,8,9,10,11,16,18],weak:10,wear:13,web:[9,10],websit:16,weekend:7,well:[0,1,3,6,7,9,10,11,15,16],went:1,were:[1,3,10,11,16],what:[1,3,4,5],whatev:[1,11,15],when:[1,2,3,7,8,9,10,11,16],whenev:1,where:[1,2,3,5,7,8,9,10,11,13,15],wherea:7,wherev:9,whether:[2,8,10,11],which:[0,1,2,3,6,7,8,9,10,11,12,13,14,15,16,18],whilst:[3,10,11,14,16],who:[1,3,6,8,11,16],whole:[2,16],whom:[3,8],whose:[9,15],why:[1,3,6,16],wide:[1,8,16],widescreen:1,widespread:1,width:1,wiki:[3,16],wikipedia:16,window:[3,4,11,14,17],wire:18,wirecommand:16,wiretransact:[2,10,11,15],wish:[3,8,10,11,16,18],within:[0,2,3,9,14],withkei:11,withnewown:11,without:1,withoutown:16,won:[8,10,11,14,16],word:[1,2],work:[1,2,3,4,5,6,7,8,9,10,11,12,14,15,16],worker:1,world:[3,10,11,16],worn:16,worri:[1,6,11],worst:3,worth:[1,16],worthless:10,would:[1,2,3,6,7,8,9,10,11,15,16,18],wouldn:[10,16],wrap:[1,9,11,15,16,18],wrapper:11,write:[1,2,5,6,9],written:[0,3,6,7,16],wrong:[1,11,14],wrote:3,wtx:[2,10,11],www:[0,4],year:7,yet:[1,3,7,11,12,16],yield:[3,11],you:[0,1,3,4,6,8,9,10,11,14,16,17,18],your:[1,3,4,5,8],your_usernam:4,yourself:3,zero:[3,16],zip:[3,9]},titles:["Building the documentation","Code style guide","Consensus Model","Data model","Getting set up","Welcome to the Corda repository!","What’s included?","The Interest Rate Swap Contract","Networking and messaging","Node administration","Writing oracle services","Protocol state machines","Release notes","Release process","Running the demos","Transaction Data Types","Writing a contract","Using the visualiser","Where to start"],titleterms:{"class":16,"function":16,about:4,administr:9,adopt:3,amount:15,api:16,approach:10,assert:[1,10],asset:16,attach:9,base:16,basic:10,bitcoin:3,build:0,buyer:11,cash:15,check:16,code:1,command:16,comment:1,commerci:16,comparison:3,complain:4,con:3,consensu:2,continu:10,contract:[6,7,15,16],corda:5,creat:7,cut:13,data:[3,10,15],date:15,demo:[14,18],detail:7,document:0,download:9,error:1,ethereum:3,fix:9,framework:10,fungibleasset:15,gener:[1,16],get:4,group:16,guid:1,how:16,implement:[2,8,10,11],includ:6,instanc:7,intellij:4,interest:[7,9],interfac:8,introduct:[10,11],known:10,kotlin:6,lack:4,length:1,lifecycl:7,line:1,machin:11,manag:11,map:8,memori:8,messag:8,method:11,mileston:12,model:[2,3],monitor:9,multipl:2,name:1,network:8,node:9,non:16,notari:2,note:12,occasion:10,oracl:10,orient:16,overview:3,paper:16,parti:[11,15],pro:3,process:13,progress:11,protocol:11,publickei:15,publicli:10,rate:[7,9],rational:3,releas:[12,13],repositori:5,requir:[0,16],run:14,sdk:4,seller:11,servic:[8,10],set:4,smart:16,space:1,start:[16,18],state:[11,15,16],step:13,style:[1,3],support:15,suspend:11,swap:7,technic:7,test:16,theori:11,thread:1,timestamp:2,track:11,trade:11,tradeoff:3,trader:[14,18],transact:15,two:[10,11],type:15,unreleas:12,upload:9,usag:2,utxo:3,valid:2,vari:10,verifi:16,visualis:17,welcom:5,what:6,where:18,without:4,write:[10,16],your:[9,16]}}) \ No newline at end of file +Search.setIndex({envversion:47,filenames:["building-the-docs","codestyle","consensus","data-model","event-scheduling","getting-set-up","index","inthebox","irs","messaging","node-administration","oracles","protocol-state-machines","release-notes","release-process","running-the-demos","transaction-data-types","tutorial-contract","visualiser","where-to-start"],objects:{},objnames:{},objtypes:{},terms:{"0_xx":5,"1mb":12,"8u45":5,"_before_":12,"_do_":12,"_foo":1,"_is_":12,"_mbeans_":10,"abstract":[3,12,13],"boolean":[3,17],"break":[11,14,17],"byte":[1,3,7,12],"case":[1,2,3,9,11,12,13,16,17],"catch":[1,5,12],"class":[],"default":[1,5,7,12,13,15,17],"enum":13,"export":[10,12,19],"final":[2,3,5,8,9,12,17],"float":[4,7,8],"function":[],"import":[1,3,4,5,9,12,14,17,19],"instanceof":17,"int":[1,2,17],"long":[1,3,4,9,12,17],"new":[1,2,3,5,6,7,8,9,10,12,13,14,17,19],"null":[4,11,17],"public":[1,3,7,9,10,11,12,16,17],"return":[1,2,4,8,9,10,11,12,13,17,19],"short":[4,9,14,17],"static":[3,11,12,17,19],"super":1,"switch":[7,12,13,17],"throw":[1,2,11,12,17],"transient":12,"true":[3,9,11,17,18],"try":[1,3,12,15,17,18,19],"var":17,"void":17,"while":16,abil:[3,9],abl:[2,3,9,11,13],abort:2,about:[],abov:[1,3,8,9,12,17],absolut:3,abstractnod:11,accept:[1,2,3,9,12,17],acceptablepric:12,access:[1,3,5,9,10,11,12,17],accid:12,accident:1,accompani:1,accord:19,accordingli:9,account:[3,16],accrual:8,accur:11,accuraci:3,achiev:[2,3,9],ack:13,acknowledg:12,across:[3,12,13],act:[2,3,9,11,12],action:[4,17,19],activ:[4,8,15],actor:[1,3,12],actual:[5,8,9,11,12,17],adapt:[1,11,12],add:[1,9,10,12,16,17],addarg:17,addcommand:12,addinputst:[12,17],addit:[1,2,3,16,17],addition:[11,12,14],addmessagehandl:[9,13],addoutputst:[12,17],address:[2,3,9,12,17],adjust:[1,8,19],admin:5,administr:[],advanc:[6,8],advantag:3,adventur:19,advertis:11,advertisedservic:2,advic:14,affect:[5,11],affection:17,affinityexecutor:1,afraid:1,after:[2,3,4,5,7,8,11,12,17,18],again:[3,8,9,11,12,15,17],against:[3,4,8,12,17],agent:10,aggreg:[3,17],agre:[4,8,12],agreement:[3,8,16],ahead:12,aim:[1,3],algorithm:[3,7,13,17,18],alic:[17,18],aliceaddr:9,alicegetsback:[17,18],alicenod:9,aliv:12,all:[0,1,2,3,5,8,9,10,11,12,13,14,15,17,19],allevi:2,allow:[1,2,3,4,7,8,11,12,16,17,19],allpossiblerecipi:9,almost:[12,17],along:[2,7,9,11,12,17],alreadi:[1,4,11,12,13,17],alright:12,also:[1,2,3,4,5,8,9,10,12,15,16,17,19],alt:17,alter:[12,17],altern:[0,1,10],although:[3,7,8,9,17,19],alwai:[1,3,4,10,12,17],amounnt:12,amount:[],amqp:7,analysi:3,andresen:3,ani:[1,2,3,4,8,9,10,11,12,14,16,17,19],annot:[1,12,17],announc:14,anonym:3,anoth:[1,2,5,10,11,12,17],answer:[1,11],anticip:1,anybodi:3,anyon:[2,17],anyth:[2,3,9,11,12,17],anywher:[9,11,17],apach:[7,9],apart:2,api:[],app:[10,14,19],appear:17,append:10,appendix:6,appli:[1,3,8,17],applic:[3,11,19],applyfix:8,appoint:2,approach:[],appropri:[1,9],approv:[3,4,12],arbitrari:[1,3,11,12,17],arbitrarili:7,architectur:[6,11],area:[9,16],aren:[12,17,19],arg:[17,18],arguabl:11,argument:[1,3,9,12,17],aris:3,around:[3,9,11,12,14,16,17,18],arrai:[3,7,12],arrang:12,arriv:[11,12],arrow:[5,8],artemi:7,articl:[2,3,4,9,11,12,19],artifact:17,ask:[1,12,17],aspect:[4,12,19],assembl:3,assemblesharedtx:12,asset:[],assetforsal:12,assetmismatchexcept:12,assettosel:12,assettypenam:12,assign:11,assist:[4,12,17,18],associ:[2,3,4,9,16,17],assum:[3,11,12,17],assumpt:12,atom:[3,11,12,15,17],attach:[],attack:2,attempt:[3,5,6,9,12],attent:12,attest:[2,11],attribut:1,audit:[3,12],authent:2,authenticatedobject:[16,17],author:[1,2,3,9,12,14,19],authoris:12,auto:[1,17],autom:[3,4,17,19],automat:[0,4,9,12,13,17,19],avail:[0,4,8,9,10,11,14,17],avoid:[1,3,12],awai:[3,12,15],awar:[1,12],awg:14,awkward:[1,12],axi:8,back:[1,3,11,12,16,17],backend:9,background:[1,3,9],backport:14,backtick:17,backward:[12,14],bad:[1,12,17],balanc:[2,3,17],band:12,bandwidth:1,bank:[3,8,16,19],bankrupt:17,bankruptci:[3,11],barrel:13,base:[],basi:[4,8,10],basic:[],bat:15,bear:[12,17],beauti:18,becaus:[1,3,5,9,10,11,12,17],becom:[1,3,4,8,12,14],been:[2,3,5,8,11,12,13,14,17],befor:[2,3,4,7,8,11,12,13,14,16,17],beforehand:15,begin:[1,3,15,17,19],behav:17,behaviour:[2,10],behind:[12,17],belong:[],below:[1,3,4,8,12,19],benefit:[2,12,17],best:[1,15,19],bet:11,better:[1,6,7,13,17,18],between:[1,3,4,8,9,11,12,13,14,15,16,17],beyond:[3,17],big:[1,3,12,17],bigdecim:11,bilater:[7,8,13],bill:17,bin:15,binari:[3,11],bind:[2,3,11],bip:3,bit:[12,17,18,19],bitbucket:5,bitcoinj:12,blah:1,blank:[1,17],block:[1,2,3,6,9,11,12,13,17],blockchain:[3,7,12],bloom:1,bloomfilt:1,blow:15,blue:[8,18],bob:17,bobaddr:9,bobnod:9,bodi:1,boil:3,bond:17,bookkeep:[7,17],boost:7,borrow:18,both:[2,3,7,8,9,11,12,15,17],bottom:12,bound:[11,12],box:[7,19],branch:14,breach:3,bread:19,breadth:12,brief:13,briefli:[9,18],bring:3,broadcast:[3,9],broke:1,broker:[],brows:[],bug:[1,13,14],bugfix:14,bui:[12,19],builder:[13,17],built:[12,17],bulk:3,bullet:1,bunch:[15,17],bundl:3,busi:[3,4,7,9,11,12,16,17,19],businesscalendar:16,butter:19,buyer:[],buyersessionid:12,bytearrai:9,bytecod:[3,12,17],cach:9,calcul:[4,8,12,16,17],calendar:[8,11,16],calibr:3,call:[1,2,3,7,8,9,10,12,14,17],callback:[1,9,12],caller:[2,17],callerident:[],came:12,camel:1,can:[0,1,2,3,4,5,7,8,9,10,11,12,13,15,16,17,18,19],cannot:[2,3,5,11,13,17],capabl:17,capit:1,capitan:0,captur:4,care:[1,3,9,11,12],carefulli:7,cash:[],cashkt:17,cashsigningpubkei:12,cashstat:12,caus:[1,17],center:17,certain:[1,7,17],certainti:2,cev:5,chain:[3,11,12,17],challeng:3,chanc:[1,12],chang:[],changenotari:2,channel:12,charact:1,charg:11,check:[],checkabl:11,checkdepend:12,checksufficientsignatur:12,chf:16,child:12,children:12,childrenfor:12,choic:[1,2,3],choos:[2,5,17],chosen:[2,3],chronolog:4,chunk:19,circl:18,claim:[3,7,17],clash:1,clean:12,cleanup:13,clear:[12,16],clearer:[9,12],clearli:1,click:[5,18],client:[2,10,11],clock:[4,11,15],clone:[1,5],close:11,closer:2,closur:1,cloud:10,cluster:2,cmd:17,coars:3,code:[],codebas:[1,17],cognit:3,coin:3,colleagu:1,collect:[1,10,13],collector:[1,10,12],collis:1,colour:15,column:10,com:[0,5,13],combin:[3,6,17],come:[3,7,12,14],command:[],commanddata:11,commerci:[],commercial_pap:17,commercialpap:[7,17,18],commercialpapertest:[17,18],commit:[2,12,14],committedst:[],commod:16,common:[3,8,12,16,17],commonleg:8,commonli:17,commun:5,compani:11,companion:[12,17],compar:[3,9],compat:14,compel:2,compil:[],complementari:4,complet:[3,4,9,12,15,17],complex:[1,3,16,17],complic:[12,17],compon:[4,9],compos:[12,16,17],compris:8,comput:[8,11,12],concept:[2,3,4,11,12,17],conceptu:12,concern:[3,12,17],conclus:[3,11],concurrenthashmap:1,condit:[2,11,12],config:10,configur:[5,10,12,15],confirm:[2,5,9],conflict:[2,3,6],confus:12,connect:[10,17],consid:[1,3,8,11,13,14,17],consist:[3,8,12],constant:[1,17],constantli:11,constraint:11,construct:[1,2,9,11,12,17,19],constructor:[4,11,17],consult:11,consum:[2,3,4,13],consumingtx:2,consumpt:[4,11],contact:[5,12],contain:[2,3,8,9,10,11,12,14,15,16,17,19],content:[1,2,3,4,5,9,10,11,17],context:[1,3,10,11,16],continu:[],contract:[],contractst:[2,4,13,16,17,18],contractstateref:17,contrast:[3,11,12],control:[1,2,3,5,10,12,13,17,19],conveni:[1,3,17],convent:[8,12],convers:16,convert:[8,16,17],convinc:12,copi:[1,3,9,12,17,19],copyonwritearraylist:1,copyright:1,corda:[],cordapp:13,core:[9,13,16,17],corner:5,correct:[2,3,14,17],correctli:[3,11,17],correspond:17,correspondingli:1,cost:[11,17],could:[1,2,3,11,12,16,17],count:8,countabl:13,counter:[1,12],counterparti:8,countri:[11,16],coupl:[11,12],cours:[10,11,17,19],cover:[2,3,11,12,16,17,19],cp_program_id:17,creat:[],createdummyir:8,createmessag:9,creation:[3,6,8,17],creator:11,crisp:17,critic:[3,14],crop:3,curl:10,currenc:[7,8,13,16,17],current:[1,2,3,4,7,8,9,11,12,13,14,16,17,18],currentwallet:12,curv:8,custom:[2,10,13,15,16],customis:19,cut:[],cycl:1,dai:[4,8,10,11,14,16,17,18],dashboard:10,data:[],databas:[3,7,12],dataset:8,date:[],dateoffset:13,daterollconvent:16,deadlin:16,deal:[1,11,15,16],dealstat:16,debug:12,decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9:10,decd:10,decentralis:11,decid:[5,11,17],decis:[2,3],declar:[1,9,17],dedic:1,defin:[1,2,3,7,9,10,11,12,13,16,17,18,19],definit:[2,12,16,17],delai:[8,11],delet:[1,3,12,17],deliber:3,deliv:[9,16],deliveri:[7,9,12,15,17],demand:[3,16],demo:[],demonstr:[15,19],denial:2,denomin:7,dens:1,depend:[1,2,3,4,5,11,12,13,17],dependencytxid:12,deposit:[7,17],depth:17,deregist:9,deriv:[8,12,17],describ:[1,2,3,4,6,12,16,17],descript:1,deserv:14,design:[1,2,3,6,7,11,17,19],desir:[12,16,17],desktop:10,despit:[12,17],destin:9,destroi:[3,17],destroypaperatredempt:[17,18],destructur:17,detail:[],detect:1,determin:[4,8],develop:[1,3,7,9,12,13,14,15,17],devic:3,devis:3,diagram:[8,18],diamond:18,didn:[1,12,14,17],differ:[1,3,4,8,11,12,13,16,17],difficult:[9,12],digest:2,digit:[3,11,12,13,17],digitalsignatur:[2,11,12],direct:1,directli:[1,10,16],directori:[0,15,17,19],directthreadexecutor:1,dirti:17,disadvantag:3,discov:3,discuss:[3,9,16],disk:[12,13,16],disobei:11,disprov:6,disput:[2,8,17],disrupt:9,distinct:1,distinguish:17,distribut:[2,3,6,7,11,12],distrust:[2,12],divid:2,dlg:12,doc:[0,1,17],docker:10,docsit:[0,14],doe:[1,2,3,4,7,8,9,10,11,12,17,19],doesn:[1,2,3,5,9,10,11,12,15,17],dokka:0,dollar:[17,18],domain:[17,18],don:[1,3,5,7,9,12,14,17],done:[0,3,12,17],dot:8,doubl:[3,7,15,17],doubt:[1,7],down:[1,3,11,17],download:[],downsid:[1,3],drag:18,drive:[3,19],driven:15,driver:[13,19],drm:11,dsl:[13,17,18],due:[1,3,4,7,8,11,12,17],dummi:17,dummy_pubkey_1:17,duplic:17,durat:[4,11,17],dure:[1,4,8,13],dynam:[17,19],each:[1,2,3,4,7,8,9,11,12,13,14,17,19],earli:[1,17,18,19],earliest:[4,8],eas:9,easi:[1,3,7,11,17],easier:[1,12,17],easiest:17,easili:[1,11,12,15],econom:8,ed25519:13,edit:5,editor:5,effect:[3,8],either:[1,2,3,8,11,12,17,19],element:[1,3],elimin:7,ellipt:[],els:[2,3,17],emb:[4,17],embed:[3,10,11],emit:17,empti:[13,17],enabl:17,encapsul:[1,16],enclos:1,encod:11,encount:7,encrypt:7,end:[1,7,8,11,12,14,19],endpoint:10,enforc:[1,3,17],engin:17,english:[1,17],enorm:12,enough:[1,5,9,12,17,19],ensur:[1,2,3,5,9,12,14,16,17],enter:[17,19],entir:[2,3,8,9,11,17],entireti:8,entiti:[2,3,11,17],entri:[3,8,12,17],enumer:8,environ:[1,11,12],envisag:17,equal:[2,12,17],equival:[1,8,16,17],especi:[16,18],essenti:[10,11,16,17],establish:[4,15],etc:[1,8,11,12,13,14,16,17],euribor:[10,11],evalu:[8,11],even:[3,7,9,11,12,17],event:[],eventu:14,ever:[1,3],everi:[2,3,11,12,13,14,17,19],everybodi:[3,11],everyon:[2,11],everyth:[2,9,17,19],evid:11,evolut:3,evolv:[17,19],exact:[11,17],exactli:[3,9,17],examin:[1,3,11,17],exampl:[],excel:11,except:[1,12,17],excess:1,exchang:[8,12,16,17],execut:[3,4,11,16,17],executor:[1,9],exercis:17,exhaust:13,exist:[1,2,3,4,6,8,17,19],exit:17,expect:[1,4,9,12,14,17],expectedtypenam:12,expectfailureoftx:17,expens:1,experi:[3,14,19],experiment:[1,4,12,13],explain:[1,4,9,12,13],explan:1,explicit:[1,3,11,12],explicitli:[1,3,17],explor:[1,3,5,6,7,10,17,19],exploratori:9,expos:[1,4,9,10,11,12,16],exposur:8,express:[3,7,8,11,12,13,17],extend:[1,2,7,16,17],extens:[1,13,16,17],extent:3,extern:[12,19],extract:[3,10,11,12,16,17],extrem:[3,11,17],face:[7,17,18],facevalu:17,fact:[1,2,3,8,11,12,17],factor:[3,8],factori:4,fail:[9,17],failur:[12,17],fairli:[1,12],fake:[15,17,19],fals:[1,9,11,12,17],familiar:[3,17],far:[12,15,17],fashion:1,fast:[3,9,15],fault:12,featur:[1,12,13,14,17,18],feed:11,feel:[17,19],fetch:[9,10,11],few:[1,7,9,10,11,12,14,15,17],fiber:12,field:[1,8,11,12,13,17,18],file:[0,1,3,9,10,12,15,16,17,19],fill:[1,12,17],filter:1,filterisinst:17,finalis:[8,12],financ:[12,19],financi:[3,4,6,12,13],find:[0,3,10,12],fine:3,finish:[9,12],firm:17,first:[1,2,4,5,8,9,10,11,12,13,15,16,17,19],firstli:17,fit:[1,3],fix:[],fixabledealst:16,fixedleg:8,fixedlegpaymentschedul:8,fixedratepaymentev:8,fixingroledecid:4,fixingsessioninitiationhandl:4,fixof:11,flag:[10,19],flexibl:[2,3],flight:3,floatingleg:[4,8],floatinglegpaymentschedul:8,floatingratepaymentev:8,flow:[1,8,17],flux:19,fly:12,fold:1,folder:0,follow:[0,1,2,3,4,5,6,9,10,11,12,16,17,18],font:1,foo:[1,9],foobrokenexcept:1,fooutil:17,forc:[3,10,13],fordai:[4,11],forev:14,forget:[12,17],form:[2,3,4,12,17],formal:[9,17],format:[0,1,3,10],forth:12,forward:[9,11,12,14,15],found:[5,10,11,12,14,19],four:[7,17],frame:[1,12],framework:[],free:[3,11,12],freeform:17,freeli:11,frequenc:8,frequent:12,fresh:[11,17],freshkei:12,freshli:17,from:[0,1,2,3,5,7,8,9,10,11,12,13,14,16,17,18,19],front:17,frustrat:3,full:[1,2,9,12,17],fulli:[1,3,9,12,13,17],fullysign:12,fun:[2,4,11,12,17],fund:3,fundament:[2,3,6,17],fungibl:[7,16,17],fungibleasset:[],funni:12,further:[3,7,8,16],futur:[2,3,11,12,16,17,18,19],gain:7,game:12,garbag:[1,10,12],gather:17,gavin:3,gbp:16,gcd:3,gear:14,gener:[],generateirsandfixsom:8,generateissu:17,generatemov:17,generateredeem:17,generatespend:[12,17],genuin:1,get:[],getbloomfilters:1,getclass:17,getcommand:17,getfacevalu:17,getfix:8,getinput:[13,17],getinst:13,getissu:17,getkei:17,getlegalcontractrefer:17,getmaturityd:17,getnotarysignatur:2,getoutput:[13,17],getoutst:13,getown:17,getprogramref:17,getprotocoltrack:12,getsign:17,getter:17,gettim:17,getvalu:17,git:[5,14],github:0,give:[2,3,17],given:[2,3,9,11,12,17],givenpric:12,global:[1,3,11,13],glue:12,gnu:0,goal:[1,3,6,7,12,14],goe:15,gone:[12,17],good:[1,5,12,17,18,19],got:[10,12],gover:17,grade:16,gradl:5,gradlew:[5,15],grammar:1,granular:3,graph:[3,7,10,12,17,18],graphit:10,greater:1,greatest:3,green:5,groom:3,group:[],groupstat:17,guarante:14,guava:1,gui:12,hack:3,had:[2,13,17],hand:[4,12,17],handl:[1,2,3,9,12,13,17],handler:[4,9,12],happen:[1,2,3,4,11,12,14,17],happi:15,hard:[1,3,12,14],harder:[3,17],hase:8,hash:[2,3,7,10,11,12,16,17],hashcod:17,hashmap:[],hasn:5,hassl:12,hat:14,have:[1,2,3,4,5,7,8,9,11,12,13,14,15,17,19],haven:17,heap:12,hearn:3,heart:17,heavi:14,heavili:3,hedg:8,heirarchi:1,held:17,hell:12,hello:12,help:[1,3,4,9,12],helper:[8,9,17],henc:[2,3,8],her:[17,18],here:[1,3,7,9,10,11,12,13,16,17,18,19],hierarch:12,hierarchi:12,high:[3,11,12],higher:[1,2,5,17],highlight:[13,17],histori:[2,12],hit:[3,5],hold:[3,9],holder:[1,3,17],holidai:[8,11,16],home:5,hood:12,hopefulli:19,hotspot:1,how:[],howev:[2,3,8,9,11,12,16,17],html:[0,1],http:[0,5,10,11,15,17,19],hub:12,human:[3,11,12],hundr:12,hurt:12,hypothesi:6,idea:[1,3,5,7,12,17,19],ideal:[12,17],ident:[2,3,11,12,16,17],identifi:[3,7,8,9,10,11,12,16],identityless:3,identityservic:12,ignor:17,illeg:11,illegalargumentexcept:[1,11,12,17],illegalstateexcept:[1,17],illustr:1,imagin:[1,12,17],immedi:[3,17],immut:[1,3,8,11,17],imper:1,implement:[],impli:12,implic:[2,3],implicitli:8,impos:[11,12,17],imposs:[3,11],improv:[3,13,14,17,18],inbackground:9,includ:[],incorpor:11,increas:[1,9],indent:1,independ:[2,11],index:[3,4,5,8,17],indexsourc:4,indic:[1,4,8,9,12,17],individu:[1,9,17],industri:[6,7,10],infer:17,infix:17,influenc:10,info:12,inform:[1,2,3,12,16,17],infrastructur:[3,7,10],inher:3,inherit:[1,9,17],init:11,initi:[2,9,12,13,17,19],initialis:2,inmemorymessagingtest:9,inmemoryuniquenessprovid:[],inoutgroup:17,input:[2,3,11,12,13,16,17,18],inputindex:2,insert:[1,9,10,11],insid:[3,9,12,15,17],instal:[0,4,5,15],installdist:15,instanc:[],instant:[1,4,11,12,17],instanti:[3,4,12,13],instead:[1,3,4,7,13,17,19],instig:2,institut:[3,7],institutionrefer:17,instruct:[10,17],instrument:[4,8],insuffici:3,insufficientbalanceexcept:17,integ:[13,17],integr:[1,11,12,13,18],intellig:1,intend:[1,3,10,11,12,16],intent:[11,17,18],intention:1,inter:7,interact:[1,3,11,12],interchang:16,interest:[],interestrateswap:7,interfac:[],intern:[1,7,9,17],internalis:1,interop:[7,17],interpret:[1,3,17],intersect:17,interv:16,introduc:[1,2,4,11,13,16,17],introduct:[],intuit:1,invalid:[2,11,12,17],invari:17,investig:12,invoc:9,invok:[1,3,4,9,10,12,13,17],involv:[2,3,9,11,12,16,17,19],iou:[],ipsa:11,irrelev:4,irsdemo:15,irsexport:8,irstest:8,irsutil:8,isaft:17,isempti:17,isinst:12,isn:[1,12,17,19],issu:[2,3,7,9,11,14,16,17,18,19],issuanc:[12,16,17,18],issuer:[3,17],item:17,iter:[12,14,17],itself:[2,3,4,8,9,10,11,12,17],jar:[0,3,10],jarinputstream:3,java:[1,3,4,7,9,10,12,13,17,19],javaclass:12,javacommercialpap:17,javadoc:1,jdk1:5,jdk:[5,12,13,17],jetbrain:[5,7],jira:[],jmx2graphit:10,jmx:10,jmxtran:10,job:19,join:[9,17],joint:17,jolokia:10,json:[10,19],judgement:1,jump:15,junit:17,just:[1,3,5,9,10,12,13,17,19],justifi:6,jvm:[3,7,10,12,19],kafka:9,kdoc:1,keep:[3,12,17,18],kei:[1,3,7,9,11,12,16,17],kept:12,key_mismatch_at_issu:17,keymanagementservic:12,keypair:[12,17],keyword:[1,17],kick:12,kind:[3,7,9,11,12,17,19],know:[2,3,4,7,11,12,15],knowledg:11,known:[],kotin:17,kotlin:[],kryo:[9,12],label:[12,17,18],labori:17,lack:[],land:8,languag:[1,3,5,6,7,17,18,19],larg:[3,11,12,16,17,19],larger:[1,3],last:14,latenc:[2,11],later:[1,3,7,9,11,12,16,17],latest:[1,5,13],latter:[1,17],launch:4,layer:[3,9,12],layout:18,lead:[1,3,17],leak:[2,3,12],learn:[3,6,12,15,17,19],least:[11,17],leav:[1,12],ledger:[2,3,6,8,10,11,12,13,17,18],ledgertransact:16,left:[9,12],leg:[4,7,8],legal:[2,3,11,16,17],legalcontractrefer:17,legallyidentifi:[2,11,12],legallyidentifiablenod:12,less:[12,17,18],let:[1,3,4,10,11,12,13,15,17],letter:1,level:[1,2,5,8,9,11,12,16,17],lib:0,liber:1,libor:[8,10,11],librari:[1,10,11,12,16,17],licens:1,life:19,lifecycl:[],lifetim:8,like:[1,2,3,4,5,8,9,10,11,12,14,16,17,19],likewis:17,limit:[3,6,17],line:[],linearst:16,liner:1,link:[1,3,11,12,16,17],linkabl:3,linux:[10,13],list:[0,3,9,11,12,13,14,15,16,17],listen:1,listenablefutur:12,liter:3,littl:[1,17],live:8,livelock:3,load:[2,3,15,16,17,19],loan:[8,11],local:[0,3,5,10,11,12],locald:11,localhost:10,locat:[16,17],lock:[1,17],log:[12,15],logger:12,logic:[2,3,4,7,9,12,13,17,19],longer:[1,8,11,12],look:[1,8,9,10,11,12,14,17,19],loop:[1,8,17],loquitur:11,loss:11,lot:[1,3,8,15,19],low:[2,12],lower:[1,11],lurch:12,mac:10,machin:[],maco:15,made:[1,3,6,8,12,13,14],mai:[1,3,7,9,10,11,12,14,17,19],mail:[14,15],main:[4,12,17,18,19],maintain:[2,3],maintan:11,mainten:9,major:14,make:[0,1,2,3,8,9,11,12,13,14,15,17],makenod:9,maker:7,malici:12,manag:[],mani:[1,3,4,7,9,11,12,13,16,17],manipul:16,manner:12,manual:[4,9],map:[],mappabl:17,mark:[1,12,17],markdown:1,marker:[12,17],market:6,master:[],match:[3,9,11,12,17],matter:17,matur:[8,10,11,17],maturityd:17,maven:5,maximis:3,maximum:3,maybestx:12,maybetraderequest:12,mbean:10,mean:[1,3,4,9,11,12,16],meaning:2,measur:[8,17],mechan:[13,17],meet:17,mega_corp:17,mega_corp_kei:17,mega_corp_pubkei:18,megacorp:[17,18],member:8,memori:[],menlo:1,mention:[4,12],menu:5,mere:[8,17],merg:[3,7,13,16,17],mess:12,messag:[],messagehandlerregistr:9,messagerecipi:9,messagerecipientgroup:9,messagingservic:[9,12],method:[],metric:10,middl:[1,9,12],might:[1,3,5,8,12,17],mike:3,mileston:[],mind:[1,11,12,17],mine:3,minim:[3,12],minimis:[2,3,9],minimum:[3,8],minor:14,minu:17,minut:[7,11],misc:9,miss:[1,12,17,19],missingsig:12,mission:10,mix:[1,12,17],mock:9,mode:9,model:[],modest:3,modif:17,modifi:[2,5,8,12,16,17],modul:[1,9,13,17],moment:9,monei:[11,17],monetari:17,monitor:[],month:[8,12,14],more:[1,2,3,7,8,9,10,11,12,13,15,16,17],moreexecutor:1,most:[1,3,8,9,10,11,12,17],mostli:17,move:[12,13,14,17,18],movement:[12,17],much:[1,3,7,12,13,17,19],multi:[1,7,12,17],multilater:13,multipli:8,must:[1,2,3,4,9,10,11,12,17,19],mutabl:[1,3,17],mutat:3,mutual:[2,12],myfil:10,mykeypair:12,nail:1,namedbyhash:16,namespac:12,narrow:1,nativ:12,natur:17,naval:[3,11],navistar:11,necessari:[1,2,14,15],need:[0,1,2,3,4,6,8,9,10,12,14,15,16,17,19],negoti:[3,16],neither:[12,17],nest:12,net:[8,13,17,18],nettabl:7,network:[],neutral:7,never:[1,3,11,17],newli:[4,12],newnotari:2,newown:17,newsecurerandom:13,next:[1,4,5,8,12,17],nextfixingof:4,nextscheduledact:4,nice:15,nio:1,noddi:10,node:[],nodea:15,nodeb:15,nodeinterestr:11,nodeservic:11,non:[],none:[4,12],nonemptyset:13,normal:[8,12,16,17],not_matured_at_redempt:17,notabl:1,notaris:2,notarychang:13,notarychangeprotocol:2,notaryexcept:2,notaryprotocol:2,notaryservic:13,notat:12,note:[],noth:[1,3,4,13,17],notic:[1,17],notif:9,notifi:9,notion:[3,8,17],notnul:17,now:[1,3,5,9,11,12,13,15,17,18,19],nugget:17,nullpublickei:17,number:[1,3,8,9,11,12,14,15,16,17],numer:3,obj:17,object:[1,3,4,7,8,9,10,11,12,13,16,17,18,19],oblig:[7,8,13,16],observ:[3,4,8,11,12],observatori:[3,11],obsolet:4,obtain:[],obviou:[1,2,3,11],obvious:[8,17],occasion:[],occur:[2,4,11,12,17],occurr:11,odd:[12,17],off:[9,12,17,18],offer:12,offlin:9,offset:8,often:[1,3,8,11,12,17],oftenor:11,oil:13,old:2,omit:4,onc:[0,1,2,4,7,8,9,11,12,14,16,17,19],onli:[1,2,3,7,8,9,10,11,12,13,17,18,19],onto:[1,12,17,18],opaqu:[7,9],opaquebyt:17,open:[2,3,5,11,12,15,18],openjdk:5,oper:[4,8,9,10,11,12,17],optim:1,option:[0,1,4,8,9,11,12,17,19],oracl:[],orchestr:[6,7,13,19],ordain:8,order:[0,1,2,3,7,8,9,12,16,17,18],ordinari:[3,12,17],org:[0,5,17],orient:[],origin:[16,17],originalst:2,otc:7,other:[1,2,3,4,7,8,9,11,12,15,16,17],othersid:12,otherwis:[1,4,12,17],our:[1,2,3,4,12,14,17],ourselv:[12,17,19],oursignatur:12,out:[1,2,3,4,5,7,10,11,12,17],outag:9,outcom:12,outlin:[3,12],outpoint:3,output:[2,3,11,12,13,15,16,17,18],outsid:[3,9,11,12,17,19],outstat:17,over:[1,2,3,8,9,10,11,12,16,17],overal:[2,4,9],overdu:4,overflow:1,overload:12,overnight:16,overrid:[4,12,17],overwhelm:3,own:[1,2,9,10,11,12,13,14,17,18,19],ownablest:[12,16],owned_bi:17,owner:[12,16,17],ownership:[12,17],owningkei:[12,17],p2p:12,pack:17,packet:3,page:[5,11,17],pai:[11,12,17,18],paid:[3,8],pair:[3,12,17],paper:[],paper_1:[17,18],parallel:[3,9,12],parallelis:3,paramet:[1,4,12,15,17],parameteris:3,parent:12,pars:[11,19],part:[1,2,3,4,11,12,13,16,17,19],parti:[],partial:[2,12,17],partialtx:12,particip:[2,3,13,17,19],particular:[1,2,3,10,12,13],partyandrefer:1,partyrefer:[1,17],pascal:1,pass:[2,9,12,17,18],past:[1,11,15,17,19],patch:1,path:[1,4,10,17],pattern:[1,3,17],paye:3,payer:[3,8],payment:[3,4,8,11,12,15,17,18],pdf:11,peer:[7,9,11,12],penni:17,peopl:[1,3,7,17],per:[1,3,4,19],perform:[1,2,3,4,8,11,12,15,17],perhap:[1,3,4,17],period:8,perman:17,persist:[7,9,12,13],perspect:[3,12,17],phrase:11,physic:[2,11,13],pick:[9,12,13,14,17,19],piec:[1,2,3,9,12,17],ping:9,pip:0,pki:3,place:[0,1,3,4,7,8,9,11,12,14,16,17,19],plai:12,plan:[9,15],platform:[2,3,4,6,7,8,9,11,12,16,17],pleas:[1,3,5,13,17],pluggabl:13,plugin:[5,10],point:[1,2,3,4,10,11,12,14,17],pointer:[2,12,16],pointless:1,pong:9,pool:[1,3,12],poor:3,pop:[5,9],popular:7,popup:5,port:14,posess:12,posit:[1,2,3,12],possess:2,possibl:[3,9,11,12,17],potenti:[1,2,7,12,17],pound:17,power:[3,6],practic:[3,17],pre:[0,3,8,12,17,19],preced:17,precis:[3,7,11],precondit:1,prefer:[1,3],prefix:[1,12],preliminari:9,prepar:[3,17],present:[2,6,8,11,16,17],preserv:[2,3],press:17,pretend:10,pretti:[3,12,17],prevent:17,previou:[3,13,16],previous:[4,8,11,13],price:[3,11,12],primari:[7,11],primit:17,print:15,priv:12,privaci:[1,2,3,12,13,17],privat:[1,3,12,17,19],privatefoo:1,probabl:[5,11,17,19],problem:[2,3,11,12],proce:12,procedur:12,process:[],processor:3,produc:[0,4,17,18],product:[1,4,6,7,14,16,17],profit:[17,18],profound:3,program:[1,3,9,10,12,15,16,17,19],programref:17,progress:[],progresstrack:12,project:[5,15],proof:[3,6],propag:[6,10,17],properli:12,properti:[],propos:[6,12],prose:[11,16],protect:12,protocol:[],protocollog:[4,12],protocollogicref:4,protocollogicreffactori:4,protocolstatemachin:12,protocoltrack:12,prototyp:[1,3,6,7,11,17],prove:[2,3,6,17],provid:[0,1,2,3,8,9,10,11,12,16,17,19],provision:16,pseudo:11,ptx:12,publicfoo:1,publickei:[],publicli:[],pull:5,pump:9,punish:11,purchas:[12,15],pure:[3,11],purpos:[7,12,17],push:14,put:[1,12,14,17,19],python:0,qualiti:6,quantiti:[3,7,17],quasar:12,queri:[4,8,11],question:[1,2,4,5,11],queu:9,queue:[1,9,12],quick:11,quickli:[3,9,17],quit:[1,11,12,17],r3corda:13,r3dlg:14,r3prototyp:[0,5,15],r3repositori:5,rais:2,random63bitvalu:12,random:[3,4,12,13],rang:11,rapid:[1,7,14],rate:[],ratefixprotocol:11,rather:[1,3,12,13,17],raw:[10,12],reach:[2,3,4,8,11],reachabl:12,read:[1,3,6,7,10,11,12,17,19],readabl:[7,12],reader:17,readi:[14,17],readili:16,readm:1,real:[1,9,11,17,19],realis:12,realism:9,realiti:8,realli:[1,2,3,12,17],reason:[1,3,8,12,16,17],reassign:17,recal:8,receiv:[3,8,9,11,12,14,17,18],receiveandcheckproposedtransact:12,receiveandvalidatetraderequest:12,recipi:[3,9,17],recognis:[3,11,17],recommend:[1,9,19],record:[2,4,9],recordtransact:4,recov:9,recreat:12,red:[5,8],redeem:[7,17,18],redempt:[17,18],redemptiontim:[17,18],reduc:1,redund:1,ref:[12,17],refactor:13,refer:[1,2,3,4,7,8,11,12,16,17],referenc:2,refin:7,reflect:17,refus:5,regard:2,regardless:12,regener:[8,14],regist:[1,9,10,12,19],registr:9,regular:[10,12,17],reissuanc:[3,17],reject:17,rel:[3,9],relabelablestep:12,relat:[8,17],relationship:17,releas:[],relev:[3,13,16],reli:3,reliabl:9,relianc:3,relic:10,religi:1,remain:[4,17,18],remeb:5,rememb:[1,4,5,12,17],remind:12,remot:5,remov:[9,12,17],renam:13,render:[1,12,18],repeat:[1,8,9,12],replac:[2,5,8,10,14,16,17],replic:3,repoint:2,report:9,repositori:[],repres:[1,3,8,9,11,12,16,17],represent:8,request:[2,3,9,11,12,13],requestingparti:2,requiresinglecommand:17,requirethat:17,resel:11,reserv:12,reset:8,reshap:3,resolut:[2,3,6,12],resolv:[1,12,16],resolvetransactionsprotocol:12,resourc:12,respect:[1,3,12,15,17],respend:3,respons:[2,3,4,9,11,12],rest:[2,3,7,9,10,12,19],restart:[5,12],restor:12,restrict:1,restructuredtext:0,result:[1,2,3,8,11,12,17],resultfutur:12,resum:[12,13],resurrect:12,retain:9,retri:[7,9,12],retriev:[2,8],reus:[3,12],reusabl:11,reveal:[2,3,12,17],revers:12,review:[1,13,14],revis:8,rewrit:12,right:[1,5,9,10,12,14,19],rigid:3,rigidli:1,risk:12,robust:13,role:[4,15,19],roll:[8,12,15],rollov:[16,17],root:[15,17,18],roughli:[11,14],rout:12,router:9,rule:[1,11,12,13,17],run:[],runbuy:12,runnetwork:9,runsel:12,runtim:[1,12],safe:[1,3,12,17],safeti:1,sai:[1,2,3,17],sale:[15,17],same:[1,2,3,4,7,8,9,11,12,15,17,18],sandbox:[3,4,7,17],saniti:12,satisfi:17,save:[1,17],scala:[7,17],scalabl:[1,3],scale:8,scenario:[3,19],scene:[12,17],schedul:[],schedulablest:4,scheduledact:4,scope:[3,17],scrape:10,scratch:19,screen:[1,5],script:[0,3,17],scroll:15,scrub:12,seamless:7,search:[5,12,17],second:[8,12,15,17],secondari:12,secp256r1:13,section:[3,14,17],secur:[3,4,9,12],securehash:[2,17],securerandom:13,see:[0,1,2,4,7,8,9,11,12,15,16,17,19],seed:12,seek:3,seem:3,seen:[1,8,11,12,17,18],select:[2,5,13,17],self:[],sell:[12,17,19],seller:[],sellerownerkei:12,sellersig:12,sellertradeinfo:12,semi:[3,11],send:[1,3,9,10,11,12,14,17],sendandrec:12,sender:3,sendsignatur:12,sens:[8,11,12,17],sensit:4,sent:[4,9,12,17],separ:[2,3,10,11,12,15,16,17],sequenc:[3,9],sequenti:[9,12],seri:12,serial:[7,9,17],serialis:[1,3,7,9,12,17],serializablewithkryo:17,serializeablewithkryo:17,seriou:[3,14],serious:19,server:[10,11,19],servic:[],servicehub:[4,12],session:[4,9,12],sessionid:[4,12],set:[],setof:12,setter:17,settim:12,settl:[9,11,16],settlement:12,setup:4,setupa:15,setupb:15,sever:[3,12,17,19],sha256:17,sha256sum:10,sha:[3,10],shape:3,share:[3,8,11,12,17,19],shasum:10,she:17,shortcut:7,shorthand:17,shot:9,should:[1,2,3,4,5,7,9,12,13,15,16,17,19],shoulder:1,shouldn:[12,17],show:[3,5,7,15,17,18],shown:[12,17],shutdown:12,side:[11,12],sig:17,sign:[2,3,7,8,9,11,12,16,17],signatur:[],signatureexcept:12,signaturesfromsel:12,signedtransact:[12,16,17],signer:[11,17],signific:3,significantli:8,signoff:11,signwith:[12,17],signwithecdsa:12,signwithourkei:12,silver:1,similar:[1,3,9,11,13,17],simpl:[1,3,7,8,9,10,12,17,18],simplenotaryservic:2,simpler:[3,7],simplest:[3,12,17,19],simpli:[1,2,3,9,12,16,17],simplifi:[1,3,9,16,17,19],simultan:[3,9,12,17],singl:[1,3,10,11,12,17,18,19],singlemessagerecipi:[9,12],singleton:[12,17],sit:9,site:[1,14],situat:[1,3],size:[1,3,8,12,17],skip:12,slight:17,slightli:17,slip:14,slow:[1,3],slowest:3,small:[3,4,11,12,15,17,18],smaller:13,smart:[],smm:12,smooth:17,snapshot:[3,13,14],snide:0,snippet:[2,12,17],softwar:[12,14,19],sold:[12,17,18],solv:[3,11,12],solvenc:11,some:[1,2,3,4,7,9,10,11,12,13,15,16,17,18,19],somed:17,someon:[2,3,9,17],someprofit:[17,18],someth:[1,3,5,8,15,16,17,19],sometim:[3,9,10,11,12,17],somewhat:[3,12],somewher:[17,18],sophist:3,sort:[11,12],sound:[1,12,17,18],sourc:[4,5,8,11,12],sparingli:1,special:[2,3],specialis:12,specif:[2,3,4,9,10,11,12,13,16,17,18],specifi:[0,1,2,3,7,9,11,12,13,17,19],speed:[3,12],spend:[3,7,12,17],spent:3,sphinx:0,sphinx_rtd_them:0,spirit:13,split:[3,7,13,16,17],spread:[2,9,12],spreadsheet:11,squar:18,src:[17,18,19],ssl:7,stabilis:14,stabl:14,stack:12,stage:[1,12,17,19],stai:[3,17],stake:3,standalon:11,standard:[1,6,10,12,16,17],standardis:[3,16,17],start:[],state:[],stateandref:[2,12,16,17],statehistori:2,stateless:3,statemachinemanag:12,statement:[1,3,11,12,17],stateref:[2,3,4,16],statesoftyp:12,statist:10,status:3,step:[],still:[2,3,4,12,13,17,19],stock:[3,11],stop:[1,9,12],storag:3,store:[2,12,13,16,17],stori:1,straightforward:[12,17],stream:12,stress:1,strictli:[3,8],string:[9,11,12,17],strong:7,structur:[1,3,5,7,11,12,17],studi:17,stuff:[1,12],stx:12,sub:[1,12],subclass:[12,16],subgroup:3,submiss:11,submit:[1,2,9,12],subprotocol:[2,12],subscrib:9,subtask:12,subtl:[1,3],successor:[2,4,7],succinct:1,sudo:0,suffer:3,suffic:11,suffici:[3,6,9,11,14],suffix:17,suggest:[9,17],suggestinterestrateannouncementtimewindow:4,suit:13,suitabl:[4,9,14],sum:17,sumcashbi:[12,17],sumcashornul:17,summari:[13,14],summaris:3,sun:1,superclass:[12,13,16],superior:1,supersed:3,supertyp:17,suppli:15,support:[],suppos:[12,17],suppress:[1,13],suppresswarn:1,sure:[2,13,14,15,17,19],surfac:12,surround:[1,17],surviv:12,suspend:[],swap:[],swapsignatureswithsel:12,symbol:5,synchronis:[1,3,11],syntax:[7,17],system:[2,3,7,10,11,12,13,15,17],tab:[1,5],tag:[1,14],tailor:6,take:[1,4,7,8,12,16,17,18],tamper:12,target:[0,1,3,7,10],targetrecipi:9,task:[3,4,12],team:5,technic:[],techniqu:[1,3,11,17],tell:[0,9,12],templat:16,tempor:11,temporari:3,temporarili:[12,14],tempt:17,temptat:12,ten:17,tenor:[8,10,11,16],term:[3,4,16,17],termin:[8,10,12,15],terminolog:3,test:[],test_tx_tim:17,testutil:17,testwithinmemorynetwork:9,text:[1,5,10],than:[1,2,3,6,10,12,13,17,18],thei:[1,3,4,7,8,9,10,11,12,14,15,16,17],theirsessionid:12,them:[1,3,4,5,7,8,9,10,12,14,15,16,17,19],themselv:[9,11,12,16,17],theori:[],therefor:[3,5,7,12,14,17],thi:[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19],thing:[1,3,4,7,11,12,15,16,17,19],think:[1,3,5,12,17],third:[3,15,17],thisstateref:4,those:[3,4,9,10,11,12,16,17],though:[9,10,12,17],thought:[3,7],threadsaf:1,three:[15,16,17],threshold:17,through:[3,4,8,10,12,17,19],throughput:[2,3],throwifsignaturesaremiss:12,thrown:17,thu:[1,3,4,10,11,17],tighten:17,tightli:12,time:[1,2,3,4,7,8,10,11,12,13,16,17,18],timelin:17,timestamp:[],timestampauthoritysig:12,timestampcommand:11,timestampercli:17,timestamperservic:11,timestampingauthor:12,timestampingprotocol:12,titl:5,todo:[1,12,17],togeth:[3,12,17],token:16,told:1,toledgertransact:12,toler:[2,4,11],too:[1,12,17,18],took:12,tool:[7,10],toolbar:5,top:[1,3,5,12,17],topic:[9,12,19],topriv:12,toset:12,tosignedtransact:[12,17],tostr:[1,12,17],total:[3,17],toward:14,trace:12,track:[],tracker:12,trade1:15,trade:[],trade_top:12,tradeoff:[],trader:[],traderdemo:19,traderequest:12,tradit:[3,17],traffic:[3,12],transact:[],transactionbuild:[12,13,17],transactionforverif:17,transactiongroup:17,transactiongroupdsl:18,transactiongroupfor:18,transactiongroupfortest:17,transactionst:[2,13,16],transactiontyp:13,transfer:17,transit:[6,17,19],treat:17,tree:12,tri:[3,17],tricki:[3,12],trigger:[4,11,15],trivial:[1,3],trust:[3,12],truth:12,tsa:[3,12],tsasig:12,tupl:1,ture:3,turn:[3,12,16,17,19],tutori:[6,7,11,12,13,17,19],twice:7,two:[],twopartydealprotocol:4,twopartytradeprotocol:12,txbit:12,txhash:[3,12,17],txt:10,type:[],typenam:12,typetobui:12,typic:[3,4,9,10,12,16,17,19],unacceptablepriceexcept:12,under:[0,12,14,17,19],underli:[3,8,12,16],underscor:[1,17],understand:[3,9,10,17,18,19],unexecut:17,unexpect:12,unfinish:12,unfortun:[12,17],unguess:12,unifi:19,uniform:4,unindex:5,uniqu:[2,3,11,12,13],uniquenessprovid:[],unit:[2,3,5,7,9,12,13,17,18,19],unix:[10,15],unknow:11,unless:[1,11,12,14,17,19],unlik:[5,17],unnatur:3,unnecessari:17,unpack:[12,17],unqiu:4,unread:12,unrecognis:17,unrel:17,unreleas:[],unschedul:4,unserialis:12,unset:8,unspent:3,unstart:12,unsupportedoperationexcept:17,until:[2,3,4,8,9,12,14,19],untrustworthydata:12,unus:9,unusu:17,upcom:4,updat:[3,5,9,12,13,14,17],upgrad:[5,6,13],upload:[],upon:[8,12,17],url:5,usabl:[7,14],usag:[],usd:16,useless:17,user:[0,1,3,5,7,9,11,12,13],usr:0,usual:[1,3,14],utc:4,util:[9,17],vagu:1,val:[1,2,4,9,11,12,17,18],validatingnotaryservic:2,valu:[1,3,7,8,11,17,18],valuabl:11,valuat:8,vanilla:[7,8],vari:[],variabl:[1,3,8,12,17],variant:17,variou:[1,3,7,10,12,17],vehicl:3,vendor:[7,10],verbos:17,veri:[1,3,7,11,18,19],verif:[3,7],verifi:[],verifytransact:12,versa:[8,12,16],version:[5,8,9,12,13,14,16,17],versu:12,vertic:1,via:[0,1,3,4,8,10,11,12,15,19],vice:[8,12,16],view:[1,8],virtual:[3,6],visibl:[2,3],visualis:[],vital:12,wai:[1,3,4,7,10,11,12,13,17,19],wait:[4,5,9,12,15],wallet:[3,4,12,13,17],walletservic:12,want:[1,3,5,9,10,11,12,13,17,19],weak:11,wear:14,web:[10,11],websit:17,weekend:8,well:[0,1,3,4,7,8,10,11,12,16,17],went:1,were:[1,3,11,12,17],what:[],whatev:[1,12,16],when:[1,2,3,4,8,9,10,11,12,13,17],whenev:1,where:[],wherea:8,wherev:10,whether:[2,9,11,12],which:[0,1,2,3,4,7,8,9,10,11,12,13,14,15,16,17,19],whilst:[3,11,12,15,17],whitelist:4,who:[1,3,7,9,12,13,17],whole:[2,17],whom:[3,9],whose:[10,16],why:[1,3,7,17],wide:[1,9,17],widescreen:1,widespread:1,width:1,wiki:[3,17],wikipedia:17,window:[3,5,12,15,18],wire:19,wirecommand:17,wiretransact:[2,11,12,16],wish:[3,9,11,12,13,17,19],within:[0,1,2,3,10,15],withkei:12,withnewown:12,without:[],withoutown:17,won:[9,11,12,15,17],word:[1,2],work:[1,2,3,4,5,6,7,8,9,10,11,12,13,15,16,17],worker:1,world:[3,11,12,17],worn:17,worri:[1,7,12],worst:3,worth:[1,17],worthless:11,would:[1,3,7,8,9,10,11,12,16,17,19],wouldn:[11,17],wrap:[1,10,12,13,16,17,19],wrapper:[1,2,12],write:[],written:[0,3,7,8,17],wrong:[1,12,15],wrote:3,wtx:[2,11,12],www:[0,5],year:8,yet:[1,3,7,8,12,17],yield:[3,12],you:[0,1,3,4,5,7,9,10,11,12,13,15,17,18,19],your:[],your_usernam:5,yourself:3,zero:[3,17],zip:[3,10],zone:4,zoneddatetim:4},titles:["Building the documentation","Code style guide","Consensus model","Data model","Event scheduling","Getting set up","Welcome to the Corda repository!","What’s included?","The Interest Rate Swap Contract","Networking and messaging","Node administration","Writing oracle services","Protocol state machines","Release notes","Release process","Running the demos","Data types","Writing a contract","Using the visualiser","Where to start"],titleterms:{"class":17,"function":17,about:5,administr:10,adopt:3,amount:16,api:17,approach:11,assert:[1,11],asset:17,attach:10,base:17,basic:11,bitcoin:3,build:0,buyer:12,cash:16,chang:2,check:17,code:1,command:17,comment:1,commerci:17,comparison:3,compil:1,complain:5,con:3,consensu:2,continu:11,contract:[7,8,17],corda:6,creat:8,cut:14,data:[3,11,16],date:16,demo:[15,19],detail:8,document:0,download:10,error:1,ethereum:3,event:4,exampl:4,fix:10,framework:11,fungibleasset:16,gener:[1,17],get:5,group:17,guid:1,how:[4,17],implement:[4,9,11,12],includ:7,instanc:8,intellij:5,interest:[8,10],interfac:9,introduct:[4,11,12],known:11,kotlin:7,lack:5,length:1,lifecycl:[8,16],line:1,machin:12,manag:12,map:9,memori:9,messag:9,method:12,mileston:13,model:[2,3],monitor:10,multipl:2,name:1,network:9,node:10,non:17,notari:2,note:13,obtain:2,occasion:11,oracl:11,orient:17,overview:3,paper:17,parti:[12,16],pro:3,process:14,progress:12,properti:1,protocol:12,publickei:16,publicli:11,rate:[8,10],rational:3,releas:[13,14],repositori:6,requir:[0,17],run:[2,15],schedul:4,sdk:5,seller:12,servic:[2,9,11],set:5,signatur:2,smart:17,space:1,start:[17,19],state:[12,16,17],step:14,style:[1,3],support:16,suspend:12,swap:8,technic:8,test:17,theori:12,thread:1,timestamp:2,track:12,trade:12,tradeoff:3,trader:[15,19],transact:16,two:[11,12],type:16,unreleas:13,upload:10,usag:[],utxo:3,valid:2,vari:11,verifi:17,visualis:18,warn:1,welcom:6,what:7,where:19,without:5,write:[11,17],your:[10,17]}}) \ No newline at end of file diff --git a/docs/build/html/transaction-data-types.html b/docs/build/html/transaction-data-types.html index b34ee7b810..9a9d97489c 100644 --- a/docs/build/html/transaction-data-types.html +++ b/docs/build/html/transaction-data-types.html @@ -8,7 +8,7 @@ - Transaction Data Types — R3 Corda latest documentation + Data types — R3 Corda latest documentation @@ -31,7 +31,7 @@ - + @@ -90,16 +90,16 @@
      • What’s included?
      • Getting set up
      • Data model
      • -
      • Transaction Data Types

        Appendix

          @@ -150,7 +151,7 @@
          • Docs »
          • -
          • Transaction Data Types
          • +
          • Data types
          • @@ -164,8 +165,8 @@
            -
            -

            Transaction Data Types

            +
            +

            Data types

            There is a large library of data types used in Corda transactions and contract state objects.

            Amount

            @@ -190,13 +191,15 @@ delivered (themselves referring to a currency), an -

            Contract State

            +
            +

            State

            A Corda contract is composed of three parts; the executable code, the legal prose, and the state objects that represent the details of the contract (see Data model for further detail). States essentially convert the generic template -(code and legal prose) into a specific instance. In a WireTransaction, outputs are provided as ContractState +(code and legal prose) into a specific instance. In a WireTransaction, outputs are provided as TransactionState implementations, while the inputs are references to the outputs of a previous transaction. These references are then stored as StateRef objects, which are converted to StateAndRef on demand.

            +

            The TransactionState is a container for a ContractState (the custom data used by a contract program) and additional +platform-level state information, such as the notary pointer (see Consensus model).

            A number of interfaces then extend ContractState, representing standardised functionality for states:

            @@ -223,8 +226,8 @@ interface for its subclasses’ state objects to implement. The clear use-ca intended to be readily extensible to cover other assets, for example commodities could be modelled by using a subclass whose state objects include further details (location of the commodity, origin, grade, etc.) as needed.

            -
            -

            Transaction Types

            +
            +

            Transaction lifecycle types

            The WireTransaction class contains the core of a transaction without signatures, and with references to attachments in place of the attachments themselves (see also Data model). Once signed these are encapsulated in the SignedTransaction class. For processing a transaction (i.e. to verify it) it is first converted to a @@ -244,7 +247,7 @@ for signatures present on the transaction, as well as list of parties for those

            -

            Date Support

            +

            Date support

            There are a number of supporting interfaces and classes for use by contract which deal with dates (especially in the context of deadlines). As contract negotiation typically deals with deadlines in terms such as “overnight”, “T+3”, etc., it’s desirable to allow conversion of these terms to their equivalent deadline. Tenor models the interval @@ -265,7 +268,7 @@ dates used.

          • Protocol state machines
          • Writing oracle services
          • +
          • Event scheduling

          Appendix

          Appendix

          Appendix

            diff --git a/docs/source/codestyle.rst b/docs/source/codestyle.rst index ed05f4411e..aeebb4f04d 100644 --- a/docs/source/codestyle.rst +++ b/docs/source/codestyle.rst @@ -213,3 +213,10 @@ Notably: collection wrappers, if that is appropriate. * If the code following "get()" is succinct, prefer a one-liner formatting of the public property as above, otherwise put the "get()" on the line below, indented. + +6. Compiler warnings +#################### + +We do not allow compiler warnings, except in the experimental module where the usual standards do not apply and warnings +are suppressed. If a warning exists it should be either fixed or suppressed using @SuppressWarnings and if suppressed +there must be an accompanying explanation in the code for why the warning is a false positive. \ No newline at end of file diff --git a/docs/source/event-scheduling.rst b/docs/source/event-scheduling.rst new file mode 100644 index 0000000000..9c2cacfd92 --- /dev/null +++ b/docs/source/event-scheduling.rst @@ -0,0 +1,102 @@ +.. highlight:: kotlin +.. raw:: html + + + + +Event scheduling +================ + +This article explains our experimental approach to modelling time based events in code. It explains how a contract +state can expose an upcoming event and what action to take if the scheduled time for that event is reached. + +Introduction +------------ + +Many financial instruments have time sensitive components to them. For example, an Interest Rate Swap has a schedule +for when: + +* Interest rate fixings should take place for floating legs, so that the interest rate used as the basis for payments + can be agreed. +* Any payments between the parties are expected to take place. +* Any payments between the parties become overdue. + +Each of these is dependent on the current state of the financial instrument. What payments and interest rate fixings +have already happened should already be recorded in the state, for example. This means that the *next* time sensitive +event is thus a property of the current contract state. By next, we mean earliest in chronological terms, that is still +due. If a contract state is consumed in the UTXO model, then what *was* the next event becomes irrelevant and obsolete +and the next time sensitive event is determined by any successor contract state. + +Knowing when the next time sensitive event is due to occur is useful, but typically some *activity* is expected to take +place when this event occurs. We already have a model for business processes in the form of the protocol state machines, +so in the platform we have introduced the concept of *scheduled activities* that can invoke protocol state machines +at a scheduled time. A contract state can optionally described the next scheduled activity for itself. If it omits +to do so, then nothing will be scheduled. + +How to implement scheduled events +--------------------------------- + +There are two main steps to implementing scheduled events: + +* Have your ``ContractState`` implementation also implement ``SchedulableState``. This requires a method named + ``nextScheduledActivity`` to be implemented which returns an optional ``ScheduledActivity`` instance. + ``ScheduledActivity`` captures what ``ProtocolLogic`` instance each node will run, to perform the activity, and when it + will run is described by a ``java.time.Instant``. Once your state implements this interface and is tracked by the + wallet, it can expect to be queried for the next activity when recorded via the ``ServiceHub.recordTransactions`` + method during protocols execution. +* If nothing suitable exists, implement a ``ProtocolLogic`` to be executed by each node as the activity itself. + The important thing to remember is that each node that is party to the transaction, in the current implementation, + will execute the same ``ProtocolLogic`` so that needs to establish roles in the business process based on the contract + state and the node it is running on, and follow different but complementary paths through the business logic. + +.. note:: The scheduler's clock always operates in the UTC time zone for uniformity, so any time zone logic must be + performed by the contract, using ``ZonedDateTime``. + +In the short term, until we have automatic protocol session set up, you will also likely need to install a network +handler to help with obtaining a unqiue and secure random session. An example is described below. + +The production and consumption of ``ContractStates`` is observed by the scheduler and the activities associated with +any consumed states are unscheduled. Any newly produced states are then queried via the ``nextScheduledActivity`` +method and if they do not return ``null`` then that activity is scheduled based on the content of the +``ScheduledActivity`` object returned. + +An example +---------- + +Let's take an example of the Interest Rate Swap fixings for our scheduled events. The first task is to implement the +``nextScheduledActivity`` method on the ``State``. + + +.. container:: codeset + + .. sourcecode:: kotlin + + override fun nextScheduledActivity(thisStateRef: StateRef, + protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity? { + val nextFixingOf = nextFixingOf() ?: return null + + // This is perhaps not how we should determine the time point in the business day, but instead expect the + // schedule to detail some of these aspects. + val (instant, duration) = suggestInterestRateAnnouncementTimeWindow(index = nextFixingOf.name, + source = floatingLeg.indexSource, + date = nextFixingOf.forDay) + return ScheduledActivity(protocolLogicRefFactory.create(TwoPartyDealProtocol.FixingRoleDecider::class.java, + thisStateRef, duration), instant) + } + +The first thing this does is establish if there are any remaining fixings. If there are none, then it returns ``null`` +to indicate that there is no activity to schedule. Otherwise it calculates the ``Instant`` at which the interest rate +should become available and schedules an activity at that time to work out what roles each node will take in the fixing +business process and to take on those roles. That ``ProtocolLogic`` will be handed the ``StateRef`` for the interest +rate swap ``State`` in question, as well as a tolerance ``Duration`` of how long to wait after the activity is triggered +for the interest rate before indicating an error. + +.. note:: The use of the factory to create a ``ProtocolLogicRef`` instance to embed in the ``ScheduledActivity``. This is a + way to create a reference to the ``ProtocolLogic`` class and it's constructor parameters to instantiate that can be + checked against a per node whitelist of approved and allowable types as part of our overall security sandboxing. + +As previously mentioned, we currently need a small network handler to assist with session setup until the work to +automate that is complete. See the interest rate swap specific implementation ``FixingSessionInitiationHandler`` which +is responsible for starting a ``ProtocolLogic`` to perform one role in the fixing protocol with the ``sessionID`` sent +by the ``FixingRoleDecider`` on the other node which then launches the other role in the fixing protocol. Currently +the handler needs to be manually installed in the node. diff --git a/docs/source/index.rst b/docs/source/index.rst index f18a72c5a4..df3e876da5 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -41,6 +41,7 @@ Read on to learn: tutorial-contract protocol-state-machines oracles + event-scheduling .. toctree:: :maxdepth: 2 diff --git a/docs/source/inthebox.rst b/docs/source/inthebox.rst index 690932881c..25ed8e2afa 100644 --- a/docs/source/inthebox.rst +++ b/docs/source/inthebox.rst @@ -1,46 +1,46 @@ What's included? ================ -The current prototype consists of a small amount of code that defines: +The Corda prototype currently includes: -* Key data structures. +* A peer to peer network with message persistence and delivery retries. +* Key data structures for defining contracts and states. +* Smart contracts: + * Cash + * Cash obligations + * Interest rate swaps + * Commercial paper (implemented in both Java and Kotlin for comparison) * Algorithms that work with them, such as serialising, hashing, signing, and verification of the signatures. -* Two smart contracts that implement a notion of a cash claim and basic commercial paper (implemented twice, in two - different programming languages). These are simplified versions of the real things. -* Unit tests that check the algorithms do what is expected, and which verify the behaviour of the smart contracts. -* API documentation and tutorials (what you're reading) -* A simple standalone node that uses an embedded message queue broker as its P2P messaging layer. -* A trading demo that runs the node in either a listening/buying mode, or a connecting/selling mode, and swaps some - fake commercial paper assets for some self-issued IOU cash, using a generic *protocol framework*. -* It also includes two oracles: one for precise timestamping and another for interest rate swaps. +* API documentation and tutorials (what you're reading). +* A business process orchestration framework. +* Notary infrastructure for precise timestamping, and elimination of double spending without a blockchain. +* A simple REST API. Some things it does not currently include but should gain later are: * Sandboxing, distribution or publication of smart contract code -* A peer to peer network * Database persistence -* An API for integrating external software * A user interface for administration * Many other things -You can browse `the JIRA bug tracker `_. - The prototype's goal is rapid exploration of ideas. Therefore in places it takes shortcuts that a production system would not in order to boost productivity: * It uses an object graph serialization framework instead of a well specified, vendor neutral protocol. -* It uses secp256r1, an obsolete elliptic curve. * It uses the default, out of the box Apache Artemis MQ protocol instead of AMQP/1.0 (although switching should be easy) +* There is no inter-node SSL or other encryption yet. Contracts --------- The primary goal of this prototype is to implement various kinds of contracts and verify that useful business logic can be expressed with the data model, developing and refining an API along the way. To that end there are currently -two contracts in the repository: +four contracts in the repository: 1. Cash 2. Commercial paper +3. Nettable obligations +4. Interest rate swaps ``Cash`` implements the idea of a claim on some quantity of deposits at some institutional party, denominated in some currency, identified by some *deposit reference*. A deposit reference is an opaque byte array which is usable by @@ -57,12 +57,14 @@ contract is implemented twice, once in Java and once in a language called Kotlin ``InterestRateSwap`` implements a vanilla OTC same currency bilateral fixed / floating leg swap. For further details, see :doc:`irs` +``Obligation`` implements a bilaterally or multi-laterally nettable, fungible obligation that can default. + Each contract comes with unit tests. Kotlin ------ -The prototype is written in a language called `Kotlin `_. Kotlin is a language that targets the JVM +Corda is written in a language called `Kotlin `_. Kotlin is a language that targets the JVM and can be thought of as a simpler Scala, with much better Java interop. It is developed by and has commercial support from JetBrains, the makers of the IntelliJ IDE and other popular developer tools. @@ -71,11 +73,4 @@ Java for industrial use and as such, the syntax was carefully designed to be rea the language, after only a few minutes of introduction. Due to the seamless Java interop the use of Kotlin to extend the platform is *not* required and the tutorial shows how -to write contracts in both Kotlin and Java. You can `read more about why Kotlin is a potentially strong successor to Java here `_. - -Kotlin programs use the regular Java standard library and ordinary Java frameworks. Frameworks used at this time are: - -* JUnit for unit testing -* Kryo for serialisation (this is not intended to be permanent) -* Gradle for the build -* Guava for a few utility functions +to write contracts in both Kotlin and Java. You can `read more about why Kotlin is a potentially strong successor to Java here `_. \ No newline at end of file diff --git a/docs/source/release-notes.rst b/docs/source/release-notes.rst index 28a10605f7..b78680b575 100644 --- a/docs/source/release-notes.rst +++ b/docs/source/release-notes.rst @@ -6,27 +6,72 @@ Here are brief summaries of what's changed between each snapshot release. Unreleased ---------- -Here are changes in git master that haven't yet made it to a snapshot release: +There are currently no unreleased changes. -* Made the ``NotaryService`` extensible, we now have both validating and non-validating notaries. -* Added a protocol for changing the notary for a state. -* Every ``ContractState`` now has to specify a *participants* field, which is a list of parties that are able to - consume this state in a valid transaction. This is used for e.g. making sure all relevant parties obtain the updated - state when changing a notary. -* Introduced ``TransactionState``, which wraps ``ContractState``, and is used when defining a transaction output. - The notary field is moved from ``ContractState`` into ``TransactionState``. -* Every transaction now has a *type* field, which specifies custom build & validation rules for that transaction type. - Currently two types are supported: +Milestone 1 +----------- - - **General**. Runs the default build and validation logic. - - **NotaryChange**. Contract code is not run during validation, checks that the notary field is the only difference - between the inputs and outputs. +Highlights of this release: -* The cash contract has moved from com.r3corda.contracts to com.r3corda.contracts.cash. -* Amount class is now generic, to support non-currency types (such as assets, or currency with additional information). +* Event scheduling. States in the ledger can now request protocols to be invoked at particular times, for states + considered relevant by the wallet. +* Upgrades to the notary/consensus service support: + + * There is now a way to change the notary controlling a state. + * You can pick between validating and non-validating notaries, these let you select your privacy/robustness tradeoff. + +* A new obligation contract that supports bilateral and multilateral netting of obligations, default tracking and + more. +* Improvements to the financial type system, with core classes and contracts made more generic. +* Switch to a better digital signature algorithm: ed25519 instead of the previous JDK default of secp256r1. +* A new integration test suite. +* A new Java unit testing DSL for contracts, similar in spirit to the one already developed for Kotlin users (which + depended on Kotlin specific features). +* An experimental module, where developers who want to work with the latest Corda code can check in contracts/cordapp + code before it's been fully reviewed. Code in this module has compiler warnings suppressed but we will still make + sure it compiles across refactorings. +* Persistence improvements: transaction data is now stored to disk and automatic protocol resume is now implemented. +* Many smaller bug fixes, cleanups and improvements. + +We have new documentation on: + +* :doc:`event-scheduling` +* :doc:`transaction-data-types` +* :doc:`consensus` + +Summary of API changes (not exhaustive): + +* Notary/consensus service: + + * ``NotaryService`` is now extensible. + * Every ``ContractState`` now has to specify a *participants* field, which is a list of parties that are able to + consume this state in a valid transaction. This is used for e.g. making sure all relevant parties obtain the updated + state when changing a notary. + * Introduced ``TransactionState``, which wraps ``ContractState``, and is used when defining a transaction output. + The notary field is moved from ``ContractState`` into ``TransactionState``. + * Every transaction now has a *type* field, which specifies custom build & validation rules for that transaction type. + Currently two types are supported: General (runs the default build and validation logic) and NotaryChange ( + contract code is not run during validation, checks that the notary field is the only difference between the + inputs and outputs). + ``TransactionBuilder()`` is now abstract, you should use ``TransactionType.General.Builder()`` for building transactions. + +* The cash contract has moved from ``com.r3corda.contracts`` to ``com.r3corda.contracts.cash`` +* ``Amount`` class is now generic, to support non-currency types such as physical assets. Where you previously had just + ``Amount``, you should now use ``Amount``. * Refactored the Cash contract to have a new FungibleAsset superclass, to model all countable assets that can be merged and split (currency, barrels of oil, etc.) -* Switched to the ed25519 elliptic curve from secp256r1. Note that this introduces a new external lib dependency. +* Messaging: + + * ``addMessageHandler`` now has a different signature as part of error handling changes. + * If you want to return nothing to a protocol, use ``Ack`` instead of ``Unit`` from now on. + +* In the IRS contract, dateOffset is now an integer instead of an enum. +* In contracts, you now use ``tx.getInputs`` and ``tx.getOutputs`` instead of ``getInStates`` and ``getOutStates``. This is + just a renaming. +* A new ``NonEmptySet`` type has been added for cases where you wish to express that you have a collection of unique + objects which cannot be empty. +* Please use the global ``newSecureRandom()`` function rather than instantiating your own SecureRandom's from now on, as + the custom function forces the use of non-blocking random drivers on Linux. Milestone 0 ----------- diff --git a/docs/source/release-process.rst b/docs/source/release-process.rst index 7116ba0b09..5cdf4201c9 100644 --- a/docs/source/release-process.rst +++ b/docs/source/release-process.rst @@ -33,10 +33,12 @@ Steps to cut a release create one, bug them to do so a day or two before the release. 4. Regenerate the docsite if necessary and commit. 5. Create a branch with a name like `release-M0` where 0 is replaced by the number of the milestone. -6. Tag that branch with a tag like `release-M0.0` -7. Push the branch and the tag to git. -8. Write up a short announcement containing the summary of new features, changes, and API breaks. Send it to the +6. Adjust the version in the root build.gradle file to take out the -SNAPSHOT and commit it on the branch. +7. Tag the branch with a tag like `release-M0.0` +8. Push the branch and the tag to git. +9. Write up a short announcement containing the summary of new features, changes, and API breaks. Send it to the r3dlg-awg mailing list. +10. On master, adjust the version number in the root build.gradle file upwards. If there are serious bugs found in the release, backport the fix to the branch and then tag it with e.g. `release-M0.1` Minor changes to the branch don't have to be announced unless it'd be critical to get all developers updated. \ No newline at end of file diff --git a/docs/source/running-the-demos.rst b/docs/source/running-the-demos.rst index 93499522a5..a064258f66 100644 --- a/docs/source/running-the-demos.rst +++ b/docs/source/running-the-demos.rst @@ -73,9 +73,7 @@ And in the second run: ./build/install/r3prototyping/bin/irsdemo --role=NodeB -The node in the first terminal will complain that it didn't know about nodeB, so restart it. It'll then find the -location and identity keys of nodeA and be happy. NodeB also doubles up as the interest rates oracle and you should -see some rates data get loaded. +NodeB also doubles up as the interest rates oracle and you should see some rates data get loaded. Now in the third terminal run: diff --git a/experimental/build.gradle b/experimental/build.gradle index 8723bc20ce..c7f8ff8c45 100644 --- a/experimental/build.gradle +++ b/experimental/build.gradle @@ -10,6 +10,13 @@ repositories { mavenCentral() } +compileKotlin { + kotlinOptions.suppressWarnings = true +} +compileTestKotlin { + kotlinOptions.suppressWarnings = true +} + dependencies { compile project(':core') compile project(':contracts') diff --git a/experimental/src/main/kotlin/com/r3corda/contracts/testing/ExperimentalTestUtils.kt b/experimental/src/main/kotlin/com/r3corda/contracts/testing/ExperimentalTestUtils.kt deleted file mode 100644 index d88cb52867..0000000000 --- a/experimental/src/main/kotlin/com/r3corda/contracts/testing/ExperimentalTestUtils.kt +++ /dev/null @@ -1,33 +0,0 @@ -package com.r3corda.contracts.testing - -import com.r3corda.contracts.Obligation -import com.r3corda.contracts.cash.Cash -import com.r3corda.core.contracts.Amount -import com.r3corda.core.contracts.Issued -import com.r3corda.core.crypto.NullPublicKey -import com.r3corda.core.crypto.Party -import com.r3corda.core.testing.MINI_CORP -import com.r3corda.core.utilities.nonEmptySetOf -import java.security.PublicKey -import java.time.Instant -import java.util.* - -object JavaExperimental { - @JvmStatic fun at(state: Obligation.State, dueBefore: Instant) = state.copy(template = state.template.copy(dueBefore = dueBefore)) - @JvmStatic fun between(state: Obligation.State, parties: Pair) = state.copy(issuer = parties.first, owner = parties.second) - @JvmStatic fun ownedBy(state: Obligation.State, owner: PublicKey) = state.copy(owner = owner) - @JvmStatic fun issuedBy(state: Obligation.State, party: Party) = state.copy(issuer = party) - - @JvmStatic fun OBLIGATION_DEF(issued: Issued) - = Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(issued), Instant.parse("2020-01-01T17:00:00Z")) - @JvmStatic fun OBLIGATION(amount: Amount>) = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP, - OBLIGATION_DEF(amount.token), amount.quantity, NullPublicKey) -} -infix fun Obligation.State.`at`(dueBefore: Instant) = JavaExperimental.at(this, dueBefore) -infix fun Obligation.State.`between`(parties: Pair) = JavaExperimental.between(this, parties) -infix fun Obligation.State.`owned by`(owner: PublicKey) = JavaExperimental.ownedBy(this, owner) -infix fun Obligation.State.`issued by`(party: Party) = JavaExperimental.issuedBy(this, party) - -// Allows you to write 100.DOLLARS.OBLIGATION -val Issued.OBLIGATION_DEF: Obligation.StateTemplate get() = JavaExperimental.OBLIGATION_DEF(this) -val Amount>.OBLIGATION: Obligation.State get() = JavaExperimental.OBLIGATION(this) diff --git a/experimental/src/test/kotlin/com/r3corda/contracts/universal/FXSwap.kt b/experimental/src/test/kotlin/com/r3corda/contracts/universal/FXSwap.kt index 845cdd2094..9ef5779089 100644 --- a/experimental/src/test/kotlin/com/r3corda/contracts/universal/FXSwap.kt +++ b/experimental/src/test/kotlin/com/r3corda/contracts/universal/FXSwap.kt @@ -34,20 +34,20 @@ class FXSwap { transaction { output { inState } - this `fails requirement` "transaction has a single command" + this `fails with` "transaction has a single command" tweak { - arg(roadRunner.owningKey) { UniversalContract.Commands.Issue() } - this `fails requirement` "the transaction is signed by all liable parties" + command(roadRunner.owningKey) { UniversalContract.Commands.Issue() } + this `fails with` "the transaction is signed by all liable parties" } tweak { - arg(wileECoyote.owningKey) { UniversalContract.Commands.Issue() } - this `fails requirement` "the transaction is signed by all liable parties" + command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() } + this `fails with` "the transaction is signed by all liable parties" } - arg(wileECoyote.owningKey, roadRunner.owningKey) { UniversalContract.Commands.Issue() } + command(wileECoyote.owningKey, roadRunner.owningKey) { UniversalContract.Commands.Issue() } - this.accepts() + this.verifies() } } @@ -59,13 +59,13 @@ class FXSwap { output { outState2 } tweak { - arg(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") } - this `fails requirement` "action must be defined" + command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") } + this `fails with` "action must be defined" } - arg(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") } + command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") } - this.accepts() + this.verifies() } } @@ -76,8 +76,8 @@ class FXSwap { output { outState1 } output { outState2 } - arg(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") } - this `fails requirement` "action must be authorized" + command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") } + this `fails with` "action must be authorized" } } @@ -87,8 +87,8 @@ class FXSwap { input { inState } output { outState1 } - arg(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") } - this `fails requirement` "output state must match action result state" + command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") } + this `fails with` "output state must match action result state" } } } \ No newline at end of file diff --git a/experimental/src/test/kotlin/com/r3corda/contracts/universal/ZeroCouponBond.kt b/experimental/src/test/kotlin/com/r3corda/contracts/universal/ZeroCouponBond.kt index bfb830e03a..50dff26651 100644 --- a/experimental/src/test/kotlin/com/r3corda/contracts/universal/ZeroCouponBond.kt +++ b/experimental/src/test/kotlin/com/r3corda/contracts/universal/ZeroCouponBond.kt @@ -47,16 +47,16 @@ class ZeroCouponBond { transaction { output { inState } - this `fails requirement` "transaction has a single command" + this `fails with` "transaction has a single command" tweak { - arg(roadRunner.owningKey) { UniversalContract.Commands.Issue() } - this `fails requirement` "the transaction is signed by all liable parties" + command(roadRunner.owningKey) { UniversalContract.Commands.Issue() } + this `fails with` "the transaction is signed by all liable parties" } - arg(wileECoyote.owningKey) { UniversalContract.Commands.Issue() } + command(wileECoyote.owningKey) { UniversalContract.Commands.Issue() } - this.accepts() + this.verifies() } } @@ -67,13 +67,13 @@ class ZeroCouponBond { output { outState } tweak { - arg(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") } - this `fails requirement` "action must be defined" + command(wileECoyote.owningKey) { UniversalContract.Commands.Action("some undefined name") } + this `fails with` "action must be defined" } - arg(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") } + command(wileECoyote.owningKey) { UniversalContract.Commands.Action("execute") } - this.accepts() + this.verifies() } } @@ -83,8 +83,8 @@ class ZeroCouponBond { input { inState } output { outState } - arg(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") } - this `fails requirement` "action must be authorized" + command(porkyPig.owningKey) { UniversalContract.Commands.Action("execute") } + this `fails with` "action must be authorized" } } @@ -94,8 +94,8 @@ class ZeroCouponBond { input { inState } output { outStateWrong } - arg(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") } - this `fails requirement` "output state must match action result state" + command(roadRunner.owningKey) { UniversalContract.Commands.Action("execute") } + this `fails with` "output state must match action result state" } } @@ -106,26 +106,26 @@ class ZeroCouponBond { tweak { output { outStateMove } - arg(roadRunner.owningKey) { + command(roadRunner.owningKey) { UniversalContract.Commands.Move(roadRunner, porkyPig) } - this `fails requirement` "the transaction is signed by all liable parties" + this `fails with` "the transaction is signed by all liable parties" } tweak { output { inState } - arg(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) { + command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) { UniversalContract.Commands.Move(roadRunner, porkyPig) } - this `fails requirement` "output state does not reflect move command" + this `fails with` "output state does not reflect move command" } output { outStateMove} - arg(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) { + command(roadRunner.owningKey, porkyPig.owningKey, wileECoyote.owningKey) { UniversalContract.Commands.Move(roadRunner, porkyPig) } - this.accepts() + this.verifies() } } diff --git a/node/build.gradle b/node/build.gradle index f9005d9349..8a289161b5 100644 --- a/node/build.gradle +++ b/node/build.gradle @@ -1,6 +1,3 @@ -group 'com.r3cev.prototyping' -version '1.0-SNAPSHOT' - apply plugin: 'java' apply plugin: 'kotlin' apply plugin: QuasarPlugin @@ -29,24 +26,24 @@ dependencies { compile project(':contracts') compile "com.google.code.findbugs:jsr305:3.0.1" - compile "org.slf4j:slf4j-jdk14:1.7.13" + compile "org.slf4j:slf4j-jdk14:${slf4j_version}" compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version" compile "org.jetbrains.kotlin:kotlin-test:$kotlin_version" - compile "org.jetbrains.kotlinx:kotlinx-support-jdk8:0.1" + compile "org.jetbrains.kotlinx:kotlinx-support-jdk8:0.2" compile "com.google.guava:guava:19.0" // JOpt: for command line flags. - compile "net.sf.jopt-simple:jopt-simple:4.9" + compile "net.sf.jopt-simple:jopt-simple:5.0.2" // Artemis: for reliable p2p message queues. compile "org.apache.activemq:artemis-server:${artemis_version}" compile "org.apache.activemq:artemis-core-client:${artemis_version}" // JAnsi: for drawing things to the terminal in nicely coloured ways. - compile "org.fusesource.jansi:jansi:1.11" + compile "org.fusesource.jansi:jansi:1.13" // GraphStream: For visualisation compile "org.graphstream:gs-core:1.3" @@ -63,7 +60,7 @@ dependencies { compile "org.eclipse.jetty:jetty-webapp:${jetty_version}" compile "javax.servlet:javax.servlet-api:3.1.0" compile "org.jolokia:jolokia-agent-war:2.0.0-M1" - compile "commons-fileupload:commons-fileupload:1.3.1" + compile "commons-fileupload:commons-fileupload:1.3.2" // Jersey for JAX-RS implementation for use in Jetty compile "org.glassfish.jersey.core:jersey-server:${jersey_version}" @@ -76,10 +73,10 @@ dependencies { exclude group: 'com.fasterxml.jackson.core', module: 'jackson-databind' exclude group: 'com.fasterxml.jackson.core', module: 'jackson-core' } - compile ("com.fasterxml.jackson.module:jackson-module-kotlin:2.5.5-2") { + compile ("com.fasterxml.jackson.module:jackson-module-kotlin:${jackson_version}") { exclude group: 'com.fasterxml.jackson.core', module: 'jackson-annotations' } - compile "com.fasterxml.jackson.core:jackson-annotations:2.5.5" + compile "com.fasterxml.jackson.core:jackson-annotations:${jackson_version}" // Coda Hale's Metrics: for monitoring of key statistics compile "io.dropwizard.metrics:metrics-core:3.1.2" @@ -92,7 +89,7 @@ dependencies { // Unit testing helpers. testCompile 'junit:junit:4.12' - testCompile 'org.assertj:assertj-core:3.4.1' + testCompile "org.assertj:assertj-core:${assertj_version}" } quasarScan.dependsOn('classes', ':core:classes', ':contracts:classes') diff --git a/node/src/main/kotlin/com/r3corda/node/api/APIServer.kt b/node/src/main/kotlin/com/r3corda/node/api/APIServer.kt index 7e3979c16a..9883faab5f 100644 --- a/node/src/main/kotlin/com/r3corda/node/api/APIServer.kt +++ b/node/src/main/kotlin/com/r3corda/node/api/APIServer.kt @@ -11,6 +11,7 @@ import javax.ws.rs.GET import javax.ws.rs.Path import javax.ws.rs.Produces import javax.ws.rs.core.MediaType +import javax.ws.rs.core.Response /** * Top level interface to external interaction with the distributed ledger. @@ -30,6 +31,14 @@ interface APIServer { @Produces(MediaType.APPLICATION_JSON) fun serverTime(): LocalDateTime + /** + * Report whether this node is started up or not + */ + @GET + @Path("status") + @Produces(MediaType.TEXT_PLAIN) + fun status(): Response + /** * Query your "local" states (containing only outputs involving you) and return the hashes & indexes associated with them * to probably be later inflated by fetchLedgerTransactions() or fetchStates() although because immutable you can cache them diff --git a/node/src/main/kotlin/com/r3corda/node/internal/APIServerImpl.kt b/node/src/main/kotlin/com/r3corda/node/internal/APIServerImpl.kt index 4a8fd1f038..85cafc6692 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/APIServerImpl.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/APIServerImpl.kt @@ -10,6 +10,7 @@ import com.r3corda.core.serialization.SerializedBytes import com.r3corda.node.api.* import java.time.LocalDateTime import java.util.* +import javax.ws.rs.core.Response import kotlin.reflect.KParameter import kotlin.reflect.jvm.javaType @@ -17,6 +18,14 @@ class APIServerImpl(val node: AbstractNode) : APIServer { override fun serverTime(): LocalDateTime = LocalDateTime.now(node.services.clock) + override fun status(): Response { + return if (node.started) { + Response.ok("started").build() + } else { + Response.status(Response.Status.SERVICE_UNAVAILABLE).entity("not started").build() + } + } + override fun queryStates(query: StatesQuery): List { // We're going to hard code two options here for now and assume that all LinearStates are deals // Would like to maybe move to a model where we take something like a JEXL string, although don't want to develop diff --git a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt index 7d5b00a219..ae4276cbeb 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/AbstractNode.kt @@ -5,13 +5,17 @@ import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture import com.r3corda.core.RunOnCallerThread import com.r3corda.core.contracts.SignedTransaction +import com.r3corda.core.contracts.StateRef import com.r3corda.core.crypto.Party import com.r3corda.core.messaging.MessagingService import com.r3corda.core.messaging.runOnNextMessage import com.r3corda.core.node.CityDatabase +import com.r3corda.core.node.CordaPluginRegistry import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.PhysicalLocation import com.r3corda.core.node.services.* +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.protocols.ProtocolLogicRefFactory import com.r3corda.core.random63BitValue import com.r3corda.core.seconds import com.r3corda.core.serialization.deserialize @@ -24,11 +28,14 @@ import com.r3corda.node.services.api.MonitoringService import com.r3corda.node.services.api.ServiceHubInternal import com.r3corda.node.services.clientapi.NodeInterestRates import com.r3corda.node.services.config.NodeConfiguration +import com.r3corda.node.services.events.NodeSchedulerService +import com.r3corda.node.services.events.ScheduledActivityObserver import com.r3corda.node.services.identity.InMemoryIdentityService import com.r3corda.node.services.keys.E2ETestKeyManagementService import com.r3corda.node.services.network.InMemoryNetworkMapCache import com.r3corda.node.services.network.InMemoryNetworkMapService import com.r3corda.node.services.network.NetworkMapService +import com.r3corda.node.services.network.NetworkMapService.Companion.REGISTER_PROTOCOL_TOPIC import com.r3corda.node.services.network.NodeRegistration import com.r3corda.node.services.persistence.* import com.r3corda.node.services.statemachine.StateMachineManager @@ -41,14 +48,14 @@ import com.r3corda.node.services.wallet.NodeWalletService import com.r3corda.node.utilities.ANSIProgressObserver import com.r3corda.node.utilities.AddOrRemove import com.r3corda.node.utilities.AffinityExecutor +import com.r3corda.protocols.TwoPartyDealProtocol import org.slf4j.Logger import java.nio.file.FileAlreadyExistsException import java.nio.file.Files import java.nio.file.Path import java.security.KeyPair -import java.security.Security import java.time.Clock -import java.time.Instant +import java.time.Duration import java.util.* /** @@ -89,9 +96,17 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, override val walletService: WalletService get() = wallet override val keyManagementService: KeyManagementService get() = keyManagement override val identityService: IdentityService get() = identity - override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) + override val schedulerService: SchedulerService get() = scheduler override val clock: Clock = platformClock + // Internal only + override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) + override val protocolLogicRefFactory: ProtocolLogicRefFactory get() = protocolLogicFactory + + override fun startProtocol(loggerName: String, logic: ProtocolLogic): ListenableFuture { + return smm.add(loggerName, logic) + } + override fun recordTransactions(txs: Iterable) = recordTransactionsInternal(storage, txs) } @@ -112,6 +127,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, lateinit var identity: IdentityService lateinit var net: MessagingService lateinit var api: APIServer + lateinit var scheduler: SchedulerService + lateinit var protocolLogicFactory: ProtocolLogicRefFactory var isPreviousCheckpointsPresent = false private set @@ -120,6 +137,11 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, val networkMapRegistrationFuture: ListenableFuture get() = _networkMapRegistrationFuture + /** Fetch CordaPluginRegistry classes registered in META-INF/services/com.r3corda.core.node.CordaPluginRegistry files that exist in the classpath */ + protected val pluginRegistries: List by lazy { + ServiceLoader.load(CordaPluginRegistry::class.java).toList() + } + /** Set to true once [start] has been successfully called. */ @Volatile var started = false private set @@ -140,12 +162,18 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, // the identity key. But the infrastructure to make that easy isn't here yet. keyManagement = E2ETestKeyManagementService(setOf(storage.myLegalIdentityKey)) api = APIServerImpl(this) - smm = StateMachineManager(services, listOf(storage, net, wallet, keyManagement, identity, platformClock), checkpointStorage, serverThread) + scheduler = NodeSchedulerService(services) + smm = StateMachineManager(services, + listOf(storage, net, wallet, keyManagement, identity, platformClock, scheduler, interestRatesService), + checkpointStorage, + serverThread) + + protocolLogicFactory = initialiseProtocolLogicFactory() // This object doesn't need to be referenced from this class because it registers handlers on the network // service and so that keeps it from being collected. - DataVendingService(net, storage) - NotaryChangeService(net, smm) + DataVendingService(net, storage, services.networkMapCache) + NotaryChangeService(net, smm, services.networkMapCache) buildAdvertisedServices() @@ -154,6 +182,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, ANSIProgressObserver(smm) // Add wallet observers CashBalanceAsMetricsObserver(services) + ScheduledActivityObserver(services) startMessagingService() _networkMapRegistrationFuture.setFuture(registerWithNetworkMap()) @@ -163,6 +192,18 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, return this } + private fun initialiseProtocolLogicFactory(): ProtocolLogicRefFactory { + val protocolWhitelist = HashMap>() + for (plugin in pluginRegistries) { + for (protocol in plugin.requiredProtocols) { + protocolWhitelist.merge(protocol.key, protocol.value, { x, y -> x + y }) + } + } + + return ProtocolLogicRefFactory(protocolWhitelist) + } + + /** * Run any tasks that are needed to ensure the node is in a correct state before running start() */ @@ -210,13 +251,13 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, private fun updateRegistration(serviceInfo: NodeInfo, type: AddOrRemove): ListenableFuture { // Register this node against the network - val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD + val expires = platformClock.instant() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val reg = NodeRegistration(info, networkMapSeq++, type, expires) val sessionID = random63BitValue() val request = NetworkMapService.RegistrationRequest(reg.toWire(storage.myLegalIdentityKey.private), net.myAddress, sessionID) - val message = net.createMessage(NetworkMapService.REGISTER_PROTOCOL_TOPIC + ".0", request.serialize().bits) + val message = net.createMessage("$REGISTER_PROTOCOL_TOPIC.0", request.serialize().bits) val future = SettableFuture.create() - val topic = NetworkMapService.REGISTER_PROTOCOL_TOPIC + "." + sessionID + val topic = "$REGISTER_PROTOCOL_TOPIC.$sessionID" net.runOnNextMessage(topic, RunOnCallerThread) { message -> future.set(message.data.deserialize()) @@ -227,7 +268,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, } open protected fun makeNetworkMapService() { - val expires = Instant.now() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD + val expires = platformClock.instant() + NetworkMapService.DEFAULT_EXPIRATION_PERIOD val reg = NodeRegistration(info, Long.MAX_VALUE, AddOrRemove.ADD, expires) inNodeNetworkMapService = InMemoryNetworkMapService(net, reg, services.networkMapCache) } @@ -237,8 +278,8 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration, val timestampChecker = TimestampChecker(platformClock, 30.seconds) inNodeNotaryService = when (type) { - is SimpleNotaryService.Type -> SimpleNotaryService(smm, net, timestampChecker, uniquenessProvider) - is ValidatingNotaryService.Type -> ValidatingNotaryService(smm, net, timestampChecker, uniquenessProvider) + is SimpleNotaryService.Type -> SimpleNotaryService(smm, net, timestampChecker, uniquenessProvider, services.networkMapCache) + is ValidatingNotaryService.Type -> ValidatingNotaryService(smm, net, timestampChecker, uniquenessProvider, services.networkMapCache) else -> null } } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt index 6c3ddbdda4..1c5c167b76 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/Node.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/Node.kt @@ -3,10 +3,11 @@ package com.r3corda.node.internal import com.codahale.metrics.JmxReporter import com.google.common.net.HostAndPort import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.node.CordaPluginRegistry import com.r3corda.core.node.NodeInfo +import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.ServiceType import com.r3corda.core.utilities.loggerFor -import com.r3corda.node.api.APIServer import com.r3corda.node.serialization.NodeClock import com.r3corda.node.services.config.NodeConfiguration import com.r3corda.node.services.messaging.ArtemisMessagingService @@ -25,10 +26,11 @@ import org.glassfish.jersey.server.ServerProperties import org.glassfish.jersey.servlet.ServletContainer import java.io.RandomAccessFile import java.lang.management.ManagementFactory +import java.net.InetSocketAddress import java.nio.channels.FileLock -import java.nio.file.Files import java.nio.file.Path import java.time.Clock +import java.util.* import javax.management.ObjectName class ConfigurationException(message: String) : Exception(message) @@ -52,10 +54,9 @@ class ConfigurationException(message: String) : Exception(message) * Listed clientAPI classes are assumed to have to take a single APIServer constructor parameter * @param clock The clock used within the node and by all protocols etc */ -class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration, +class Node(dir: Path, val p2pAddr: HostAndPort, val webServerAddr: HostAndPort, configuration: NodeConfiguration, networkMapAddress: NodeInfo?, advertisedServices: Set, - clock: Clock = NodeClock(), - val clientAPIs: List> = listOf()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) { + clock: Clock = NodeClock()) : AbstractNode(dir, configuration, networkMapAddress, advertisedServices, clock) { companion object { /** The port that is used by default if none is specified. As you know, 31337 is the most elite number. */ val DEFAULT_PORT = 31337 @@ -80,9 +81,7 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration private fun initWebServer(): Server { // Note that the web server handlers will all run concurrently, and not on the node thread. - - val port = p2pAddr.port + 1 // TODO: Move this into the node config file. - val server = Server(port) + val server = Server(InetSocketAddress(webServerAddr.hostText, webServerAddr.port)) val handlerCollection = HandlerCollection() @@ -110,12 +109,13 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration resourceConfig.register(ResponseFilter()) resourceConfig.register(api) - for(customAPIClass in clientAPIs) { - val customAPI = customAPIClass.getConstructor(APIServer::class.java).newInstance(api) + val webAPIsOnClasspath = pluginRegistries.flatMap { x -> x.webApis } + for (webapi in webAPIsOnClasspath) { + log.info("Add Plugin web API from attachment ${webapi.name}") + val customAPI = webapi.getConstructor(ServiceHub::class.java).newInstance(services) resourceConfig.register(customAPI) } - // 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", ServerProperties.MONITORING_STATISTICS_MBEANS_ENABLED to "true")) @@ -188,5 +188,5 @@ class Node(dir: Path, val p2pAddr: HostAndPort, configuration: NodeConfiguration val ourProcessID: String = ManagementFactory.getRuntimeMXBean().name.split("@")[0] f.setLength(0) f.write(ourProcessID.toByteArray()) - } + } } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/IRSSimulation.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/IRSSimulation.kt index 6c25d57130..674d663d4d 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/IRSSimulation.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/IRSSimulation.kt @@ -15,6 +15,7 @@ import com.r3corda.core.node.services.linearHeadsOfType import com.r3corda.core.node.services.testing.MockIdentityService import com.r3corda.core.random63BitValue import com.r3corda.core.success +import com.r3corda.node.services.FixingSessionInitiationHandler import com.r3corda.node.services.network.InMemoryMessagingNetwork import com.r3corda.node.utilities.JsonSupport import com.r3corda.protocols.TwoPartyDealProtocol @@ -30,7 +31,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten val om = JsonSupport.createDefaultMapper(MockIdentityService(network.identities)) init { - currentDay = LocalDate.of(2016, 3, 10) // Should be 12th but the actual first fixing date gets rolled backwards. + currentDateAndTime = LocalDate.of(2016, 3, 8).atStartOfDay() } private var nodeAKey: KeyPair? = null @@ -39,6 +40,11 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten private val executeOnNextIteration = Collections.synchronizedList(LinkedList<() -> Unit>()) override fun startMainSimulation(): ListenableFuture { + + // TODO: until we have general session initiation + FixingSessionInitiationHandler.register(banks[0]) + FixingSessionInitiationHandler.register(banks[1]) + val future = SettableFuture.create() nodeAKey = banks[0].keyManagement.freshKey() @@ -80,7 +86,6 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten val node1: SimulatedNode = banks[i] val node2: SimulatedNode = banks[j] - val sessionID = random63BitValue() val swaps: Map> = node1.services.walletService.linearHeadsOfType() val theDealRef: StateAndRef = swaps.values.single() @@ -89,30 +94,23 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten extraNodeLabels[node1] = "Fixing event on $nextFixingDate" extraNodeLabels[node2] = "Fixing event on $nextFixingDate" - // For some reason the first fix is always before the effective date. - if (nextFixingDate > currentDay) - currentDay = nextFixingDate - - val sideA = TwoPartyDealProtocol.Floater(node2.net.myAddress, sessionID, notary.info, theDealRef, nodeAKey!!, sessionID) - val sideB = TwoPartyDealProtocol.Fixer(node1.net.myAddress, notary.info.identity, theDealRef, sessionID) - - linkConsensus(listOf(node1, node2, regulators[0]), sideB) - linkProtocolProgress(node1, sideA) - linkProtocolProgress(node2, sideB) - - // We have to start the protocols in separate iterations, as adding to the SMM effectively 'iterates' that node - // in the simulation, so if we don't do this then the two sides seem to act simultaneously. - val retFuture = SettableFuture.create() - val futA = node1.smm.add("floater", sideA) - val futB = node2.smm.add("fixer", sideB) - executeOnNextIteration += { - Futures.allAsList(futA, futB) success { - retFuture.set(null) - } failure { throwable -> - retFuture.setException(throwable) - } + // Complete the future when the state has been consumed on both nodes + val futA = node1.services.walletService.whenConsumed(theDealRef.ref) + val futB = node2.services.walletService.whenConsumed(theDealRef.ref) + Futures.allAsList(futA, futB) success { + retFuture.set(null) + } failure { throwable -> + retFuture.setException(throwable) } + + showProgressFor(listOf(node1, node2)) + showConsensusFor(listOf(node1, node2, regulators[0])) + + // For some reason the first fix is always before the effective date. + if (nextFixingDate > currentDateAndTime.toLocalDate()) + currentDateAndTime = nextFixingDate.atTime(15, 0) + return retFuture } @@ -132,13 +130,11 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten val sessionID = random63BitValue() - val instigator = TwoPartyDealProtocol.Instigator(node2.net.myAddress, notary.info, irs, nodeAKey!!, sessionID) - val acceptor = TwoPartyDealProtocol.Acceptor(node1.net.myAddress, notary.info.identity, irs, sessionID) + val instigator = TwoPartyDealProtocol.Instigator(node2.info.identity, notary.info.identity, irs, nodeAKey!!, sessionID) + val acceptor = TwoPartyDealProtocol.Acceptor(node1.info.identity, notary.info.identity, irs, sessionID) - // TODO: Eliminate the need for linkProtocolProgress - linkConsensus(listOf(node1, node2, regulators[0]), acceptor) - linkProtocolProgress(node1, instigator) - linkProtocolProgress(node2, acceptor) + showProgressFor(listOf(node1, node2)) + showConsensusFor(listOf(node1, node2, regulators[0])) val instigatorFuture: ListenableFuture = node1.smm.add("instigator", instigator) diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt index ea7e7fb279..6245192984 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/MockNode.kt @@ -121,7 +121,11 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false, override val nearestCity: String = "Atlantis" } val node = nodeFactory.create(path, config, this, networkMapAddress, advertisedServices.toSet(), id, keyPair) - if (start) node.setup().start() + if (start) { + node.setup().start() + if (threadPerNode && networkMapAddress != null) + node.networkMapRegistrationFuture.get() // Block and wait for the node to register in the net map. + } _nodes.add(node) return node } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/Simulation.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/Simulation.kt index 2ab72e33b6..8227c1b885 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/Simulation.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/Simulation.kt @@ -1,6 +1,5 @@ package com.r3corda.node.internal.testing -import com.google.common.base.Function import com.google.common.util.concurrent.Futures import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.node.CityDatabase @@ -15,11 +14,14 @@ import com.r3corda.node.services.config.NodeConfiguration import com.r3corda.node.services.network.InMemoryMessagingNetwork import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.SimpleNotaryService +import com.r3corda.node.utilities.AddOrRemove import rx.Observable import rx.subjects.PublishSubject import java.nio.file.Path import java.security.KeyPair import java.time.LocalDate +import java.time.LocalDateTime +import java.time.ZoneOffset import java.util.* /** @@ -145,6 +147,8 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, val serviceProviders: List = listOf(notary, ratesOracle, networkMap) val banks: List = bankFactory.createAll() + val clocks = (serviceProviders + regulators + banks).map { it.services.clock as TestClock } + private val _allProtocolSteps = PublishSubject.create>() private val _doneSteps = PublishSubject.create>() val allProtocolSteps: Observable> = _allProtocolSteps @@ -156,14 +160,21 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, * The current simulated date. By default this never changes. If you want it to change, you should do so from * within your overridden [iterate] call. Changes in the current day surface in the [dateChanges] observable. */ - var currentDay: LocalDate = LocalDate.now() + var currentDateAndTime: LocalDateTime = LocalDate.now().atStartOfDay() protected set(value) { field = value _dateChanges.onNext(value) } - private val _dateChanges = PublishSubject.create() - val dateChanges: Observable = _dateChanges + private val _dateChanges = PublishSubject.create() + val dateChanges: Observable get() = _dateChanges + + init { + // Advance node clocks when current time is changed + dateChanges.subscribe { + clocks.setTo(currentDateAndTime.toInstant(ZoneOffset.UTC)) + } + } /** * A place for simulations to stash human meaningful text about what the node is "thinking", which might appear @@ -201,7 +212,15 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, return null } - protected fun linkProtocolProgress(node: SimulatedNode, protocol: ProtocolLogic<*>) { + protected fun showProgressFor(nodes: List) { + nodes.forEach { node -> + node.smm.changes.filter { it.second == AddOrRemove.ADD }.first().subscribe { + linkProtocolProgress(node, it.first) + } + } + } + + private fun linkProtocolProgress(node: SimulatedNode, protocol: ProtocolLogic<*>) { val pt = protocol.progressTracker ?: return pt.changes.subscribe { change: ProgressTracker.Change -> // Runs on node thread. @@ -211,7 +230,15 @@ abstract class Simulation(val networkSendManuallyPumped: Boolean, _allProtocolSteps.onNext(Pair(node, ProgressTracker.Change.Position(pt, pt.steps[1]))) } - protected fun linkConsensus(nodes: Collection, protocol: ProtocolLogic<*>) { + + protected fun showConsensusFor(nodes: List) { + val node = nodes.first() + node.smm.changes.filter { it.second == AddOrRemove.ADD }.first().subscribe { + linkConsensus(nodes, it.first) + } + } + + private fun linkConsensus(nodes: Collection, protocol: ProtocolLogic<*>) { protocol.progressTracker?.changes?.subscribe { change: ProgressTracker.Change -> // Runs on node thread. if (protocol.progressTracker!!.currentStep == ProgressTracker.DONE) { diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt index 009c4f0d3c..baa7085c21 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/TestClock.kt @@ -49,3 +49,9 @@ class TestClock(private var delegateClock: Clock = Clock.systemUTC()) : MutableC return delegateClock.zone } } + +/** + * A helper method to set several [TestClock]s to approximately the same time. The clocks may drift by the time it + * takes for each [TestClock] to have it's time set and any observers to execute. + */ +fun Iterable.setTo(instant: Instant) = this.forEach { it.setTo(instant) } diff --git a/node/src/main/kotlin/com/r3corda/node/internal/testing/TradeSimulation.kt b/node/src/main/kotlin/com/r3corda/node/internal/testing/TradeSimulation.kt index 571eb13252..a28baef28b 100644 --- a/node/src/main/kotlin/com/r3corda/node/internal/testing/TradeSimulation.kt +++ b/node/src/main/kotlin/com/r3corda/node/internal/testing/TradeSimulation.kt @@ -44,17 +44,25 @@ class TradeSimulation(runAsync: Boolean, latencyInjector: InMemoryMessagingNetwo val cashIssuerKey = generateKeyPair() val amount = 1000.DOLLARS `issued by` Party("Big friendly bank", cashIssuerKey.public).ref(1) val sessionID = random63BitValue() - val buyerProtocol = TwoPartyTradeProtocol.Buyer(seller.net.myAddress, notary.info.identity, - amount, CommercialPaper.State::class.java, sessionID) - val sellerProtocol = TwoPartyTradeProtocol.Seller(buyer.net.myAddress, notary.info, - issuance.tx.outRef(0), amount, seller.storage.myLegalIdentityKey, sessionID) + val buyerProtocol = TwoPartyTradeProtocol.Buyer( + seller.info.identity, + notary.info.identity, + amount, + CommercialPaper.State::class.java, + sessionID) + val sellerProtocol = TwoPartyTradeProtocol.Seller( + buyer.info.identity, + notary.info, + issuance.tx.outRef(0), + amount, + seller.storage.myLegalIdentityKey, + sessionID) - linkConsensus(listOf(buyer, seller, notary), sellerProtocol) - linkProtocolProgress(buyer, buyerProtocol) - linkProtocolProgress(seller, sellerProtocol) + showConsensusFor(listOf(buyer, seller, notary)) + showProgressFor(listOf(buyer, seller)) - val buyerFuture = buyer.smm.add("bank.$buyerBankIndex.${TwoPartyTradeProtocol.TRADE_TOPIC}.buyer", buyerProtocol) - val sellerFuture = seller.smm.add("bank.$sellerBankIndex.${TwoPartyTradeProtocol.TRADE_TOPIC}.seller", sellerProtocol) + val buyerFuture = buyer.smm.add("bank.$buyerBankIndex.${TwoPartyTradeProtocol.TOPIC}.buyer", buyerProtocol) + val sellerFuture = seller.smm.add("bank.$sellerBankIndex.${TwoPartyTradeProtocol.TOPIC}.seller", sellerProtocol) return Futures.successfulAsList(buyerFuture, sellerFuture) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/FixingSessionInitiationHandler.kt b/node/src/main/kotlin/com/r3corda/node/services/FixingSessionInitiationHandler.kt new file mode 100644 index 0000000000..102ded3db8 --- /dev/null +++ b/node/src/main/kotlin/com/r3corda/node/services/FixingSessionInitiationHandler.kt @@ -0,0 +1,22 @@ +package com.r3corda.node.services + +import com.r3corda.core.serialization.deserialize +import com.r3corda.node.internal.AbstractNode +import com.r3corda.protocols.TwoPartyDealProtocol + +/** + * This is a temporary handler required for establishing random sessionIDs for the [Fixer] and [Floater] as part of + * running scheduled fixings for the [InterestRateSwap] contract. + * + * TODO: This will be replaced with the automatic sessionID / session setup work. + */ +object FixingSessionInitiationHandler { + + fun register(node: AbstractNode) { + node.net.addMessageHandler("${TwoPartyDealProtocol.FIX_INITIATE_TOPIC}.0") { msg, registration -> + val initiation = msg.data.deserialize() + val protocol = TwoPartyDealProtocol.Fixer(initiation) + node.smm.add("fixings", protocol) + } + } +} diff --git a/node/src/main/kotlin/com/r3corda/node/services/NotaryChangeService.kt b/node/src/main/kotlin/com/r3corda/node/services/NotaryChangeService.kt index ab0b6581aa..8931ceedeb 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/NotaryChangeService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/NotaryChangeService.kt @@ -2,28 +2,29 @@ package com.r3corda.node.services import com.r3corda.core.messaging.Ack import com.r3corda.core.messaging.MessagingService -import com.r3corda.core.messaging.SingleMessageRecipient +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.node.services.api.AbstractNodeService import com.r3corda.node.services.statemachine.StateMachineManager +import protocols.AbstractStateReplacementProtocol import protocols.NotaryChangeProtocol /** * A service that monitors the network for requests for changing the notary of a state, * and immediately runs the [NotaryChangeProtocol] if the auto-accept criteria are met. */ -class NotaryChangeService(net: MessagingService, val smm: StateMachineManager) : AbstractNodeService(net) { +class NotaryChangeService(net: MessagingService, val smm: StateMachineManager, networkMapCache: NetworkMapCache) : AbstractNodeService(net, networkMapCache) { init { - addMessageHandler(NotaryChangeProtocol.TOPIC_INITIATE, - { req: NotaryChangeProtocol.Handshake -> handleChangeNotaryRequest(req) } + addMessageHandler(NotaryChangeProtocol.TOPIC, + { req: AbstractStateReplacementProtocol.Handshake -> handleChangeNotaryRequest(req) } ) } - private fun handleChangeNotaryRequest(req: NotaryChangeProtocol.Handshake): Ack { + private fun handleChangeNotaryRequest(req: AbstractStateReplacementProtocol.Handshake): Ack { val protocol = NotaryChangeProtocol.Acceptor( - req.replyTo as SingleMessageRecipient, - req.sessionID!!, + req.replyToParty, + req.sessionID, req.sessionIdForSend) - smm.add(NotaryChangeProtocol.TOPIC_CHANGE, protocol) + smm.add(NotaryChangeProtocol.TOPIC, protocol) return Ack } } diff --git a/node/src/main/kotlin/com/r3corda/node/services/api/AbstractNodeService.kt b/node/src/main/kotlin/com/r3corda/node/services/api/AbstractNodeService.kt index 0827dc1066..d688a8e834 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/api/AbstractNodeService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/api/AbstractNodeService.kt @@ -2,18 +2,19 @@ package com.r3corda.node.services.api import com.r3corda.core.messaging.Message import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.TOPIC_DEFAULT_POSTFIX import com.r3corda.core.serialization.SingletonSerializeAsToken import com.r3corda.core.serialization.deserialize import com.r3corda.core.serialization.serialize -import com.r3corda.protocols.AbstractRequestMessage +import com.r3corda.protocols.ServiceRequestMessage import javax.annotation.concurrent.ThreadSafe /** * Abstract superclass for services that a node can host, which provides helper functions. */ @ThreadSafe -abstract class AbstractNodeService(val net: MessagingService) : SingletonSerializeAsToken() { +abstract class AbstractNodeService(val net: MessagingService, val networkMapCache: NetworkMapCache) : SingletonSerializeAsToken() { /** * Register a handler for a message topic. In comparison to using net.addMessageHandler() this manages a lot of @@ -24,18 +25,18 @@ abstract class AbstractNodeService(val net: MessagingService) : SingletonSeriali * @param handler a function to handle the deserialised request and return an optional response (if return type not Unit) * @param exceptionConsumer a function to which any thrown exception is passed. */ - protected inline fun + protected inline fun addMessageHandler(topic: String, crossinline handler: (Q) -> R, crossinline exceptionConsumer: (Message, Exception) -> Unit) { net.addMessageHandler(topic + TOPIC_DEFAULT_POSTFIX, null) { message, r -> try { - val req = message.data.deserialize() - val data = handler(req) + val request = message.data.deserialize() + val response = handler(request) // If the return type R is Unit, then do not send a response - if (data.javaClass != Unit.javaClass) { - val msg = net.createMessage("$topic.${req.sessionID}", data.serialize().bits) - net.send(msg, req.replyTo) + if (response.javaClass != Unit.javaClass) { + val msg = net.createMessage("$topic.${request.sessionID}", response.serialize().bits) + net.send(msg, request.getReplyTo(networkMapCache)) } } catch(e: Exception) { exceptionConsumer(message, e) @@ -51,7 +52,7 @@ abstract class AbstractNodeService(val net: MessagingService) : SingletonSeriali * @param topic the topic, without the default session ID postfix (".0) * @param handler a function to handle the deserialised request and return an optional response (if return type not Unit) */ - protected inline fun + protected inline fun addMessageHandler(topic: String, crossinline handler: (Q) -> R) { addMessageHandler(topic, handler, { message: Message, exception: Exception -> throw exception }) diff --git a/node/src/main/kotlin/com/r3corda/node/services/api/ServiceHubInternal.kt b/node/src/main/kotlin/com/r3corda/node/services/api/ServiceHubInternal.kt index 8fc9ce4d8e..d60c20ab67 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/api/ServiceHubInternal.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/api/ServiceHubInternal.kt @@ -1,11 +1,15 @@ package com.r3corda.node.services.api +import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.contracts.SignedTransaction import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.TxWritableStorageService +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.protocols.ProtocolLogicRefFactory abstract class ServiceHubInternal : ServiceHub { abstract val monitoringService: MonitoringService + abstract val protocolLogicRefFactory: ProtocolLogicRefFactory /** * Given a list of [SignedTransaction]s, writes them to the given storage for validated transactions and then @@ -18,4 +22,18 @@ abstract class ServiceHubInternal : ServiceHub { txs.forEach { writableStorageService.validatedTransactions.addTransaction(it) } walletService.notifyAll(txs.map { it.tx }) } + + /** + * TODO: borrowing this method from service manager work in another branch. It's required to avoid circular dependency + * between SMM and the scheduler. That particular problem should also be resolved by the service manager work + * itself, at which point this method would not be needed (by the scheduler) + */ + abstract fun startProtocol(loggerName: String, logic: ProtocolLogic): ListenableFuture + + override fun invokeProtocolAsync(logicType: Class>, vararg args: Any?): ListenableFuture { + val logicRef = protocolLogicRefFactory.create(logicType, *args) + @Suppress("UNCHECKED_CAST") + val logic = protocolLogicRefFactory.toProtocolLogic(logicRef) as ProtocolLogic + return startProtocol(logicType.simpleName, logic) + } } \ No newline at end of file diff --git a/node/src/main/kotlin/com/r3corda/node/services/clientapi/NodeInterestRates.kt b/node/src/main/kotlin/com/r3corda/node/services/clientapi/NodeInterestRates.kt index 19f7b9449b..d69dd39e2a 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/clientapi/NodeInterestRates.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/clientapi/NodeInterestRates.kt @@ -1,5 +1,7 @@ package com.r3corda.node.services.clientapi +import co.paralleluniverse.fibers.Suspendable +import com.r3corda.core.RetryableException import com.r3corda.core.contracts.* import com.r3corda.core.crypto.DigitalSignature import com.r3corda.core.crypto.Party @@ -7,15 +9,24 @@ import com.r3corda.core.crypto.signWithECDSA import com.r3corda.core.math.CubicSplineInterpolator import com.r3corda.core.math.Interpolator import com.r3corda.core.math.InterpolatorFactory +import com.r3corda.core.node.CordaPluginRegistry import com.r3corda.core.node.services.ServiceType +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.utilities.ProgressTracker import com.r3corda.node.internal.AbstractNode import com.r3corda.node.services.api.AbstractNodeService import com.r3corda.node.services.api.AcceptsFileUpload -import org.slf4j.LoggerFactory +import com.r3corda.node.utilities.FiberBox import com.r3corda.protocols.RatesFixProtocol +import com.r3corda.protocols.ServiceRequestMessage +import com.r3corda.protocols.TwoPartyDealProtocol +import org.slf4j.LoggerFactory import java.io.InputStream import java.math.BigDecimal import java.security.KeyPair +import java.time.Clock +import java.time.Duration +import java.time.Instant import java.time.LocalDate import java.util.* import javax.annotation.concurrent.ThreadSafe @@ -34,23 +45,66 @@ object NodeInterestRates { /** * The Service that wraps [Oracle] and handles messages/network interaction/request scrubbing. */ - class Service(node: AbstractNode) : AcceptsFileUpload, AbstractNodeService(node.services.networkService) { + class Service(node: AbstractNode) : AcceptsFileUpload, AbstractNodeService(node.services.networkService, node.services.networkMapCache) { val ss = node.services.storageService - val oracle = NodeInterestRates.Oracle(ss.myLegalIdentity, ss.myLegalIdentityKey) + val oracle = Oracle(ss.myLegalIdentity, ss.myLegalIdentityKey, node.services.clock) private val logger = LoggerFactory.getLogger(Service::class.java) init { - addMessageHandler(RatesFixProtocol.TOPIC_SIGN, - { req: RatesFixProtocol.SignRequest -> oracle.sign(req.tx) }, - { message, e -> logger.error("Exception during interest rate oracle request processing", e) } - ) - addMessageHandler(RatesFixProtocol.TOPIC_QUERY, - { req: RatesFixProtocol.QueryRequest -> oracle.query(req.queries) }, + addMessageHandler(RatesFixProtocol.TOPIC, + { req: ServiceRequestMessage -> + if (req is RatesFixProtocol.SignRequest) { + oracle.sign(req.tx) + } + else { + /** + * We put this into a protocol so that if it blocks waiting for the interest rate to become + * available, we a) don't block this thread and b) allow the fact we are waiting + * to be persisted/checkpointed. + * Interest rates become available when they are uploaded via the web as per [DataUploadServlet], + * if they haven't already been uploaded that way. + */ + node.smm.add("fixing", FixQueryHandler(this, req as RatesFixProtocol.QueryRequest)) + Unit + } + }, { message, e -> logger.error("Exception during interest rate oracle request processing", e) } ) } + private class FixQueryHandler(val service: Service, + val request: RatesFixProtocol.QueryRequest) : ProtocolLogic() { + + companion object { + object RECEIVED : ProgressTracker.Step("Received fix request") + object SENDING : ProgressTracker.Step("Sending fix response") + } + + override val topic: String get() = RatesFixProtocol.TOPIC + override val progressTracker = ProgressTracker(RECEIVED, SENDING) + + init { + progressTracker.currentStep = RECEIVED + } + + @Suspendable + override fun call(): Unit { + val answers = service.oracle.query(request.queries, request.deadline) + progressTracker.currentStep = SENDING + send(request.replyToParty, request.sessionID, answers) + } + } + + /** + * Register the protocol that is used with the Fixing integration tests + */ + class FixingServicePlugin : CordaPluginRegistry { + override val webApis: List> = emptyList() + override val requiredProtocols: Map> = mapOf(Pair(TwoPartyDealProtocol.FixingRoleDecider::class.java.name, setOf(Duration::class.java.name, StateRef::class.java.name))) + + } + // File upload support override val dataTypePrefix = "interest-rates" override val acceptableFileExtensions = listOf(".rates", ".txt") @@ -73,25 +127,44 @@ object NodeInterestRates { * The oracle will try to interpolate the missing value of a tenor for the given fix name and date. */ @ThreadSafe - class Oracle(val identity: Party, private val signingKey: KeyPair) { + class Oracle(val identity: Party, private val signingKey: KeyPair, val clock: Clock) { + private class InnerState { + var container: FixContainer = FixContainer(emptyList()) + + } + private val mutex = FiberBox(InnerState()) + + var knownFixes: FixContainer + set(value) { + require(value.size > 0) + mutex.write { + container = value + } + } + get() = mutex.read { container } + + // Make this the last bit of initialisation logic so fully constructed when entered into instances map init { require(signingKey.public == identity.owningKey) } - @Volatile var knownFixes = FixContainer(emptyList()) - set(value) { - require(value.size > 0) - field = value - } - - fun query(queries: List): List { + /** + * This method will now wait until the given deadline if the fix for the given [FixOf] is not immediately + * available. To implement this, [readWithDeadline] will loop if the deadline is not reached and we throw + * [UnknownFix] as it implements [RetryableException] which has special meaning to this function. + */ + @Suspendable + fun query(queries: List, deadline: Instant): List { require(queries.isNotEmpty()) - val knownFixes = knownFixes // Snapshot - val answers: List = queries.map { knownFixes[it] } - val firstNull = answers.indexOf(null) - if (firstNull != -1) - throw UnknownFix(queries[firstNull]) - return answers.filterNotNull() + return mutex.readWithDeadline(clock, deadline) { + val answers: List = queries.map { container[it] } + val firstNull = answers.indexOf(null) + if (firstNull != -1) { + throw UnknownFix(queries[firstNull]) + } else { + answers.filterNotNull() + } + } } fun sign(wtx: WireTransaction): DigitalSignature.LegallyIdentifiable { @@ -120,9 +193,8 @@ object NodeInterestRates { } } - class UnknownFix(val fix: FixOf) : Exception() { - override fun toString() = "Unknown fix: $fix" - } + // TODO: can we split into two? Fix not available (retryable/transient) and unknown (permanent) + class UnknownFix(val fix: FixOf) : RetryableException("Unknown fix: $fix") /** Fix container, for every fix name & date pair stores a tenor to interest rate map - [InterpolatingRateMap] */ class FixContainer(val fixes: List, val factory: InterpolatorFactory = CubicSplineInterpolator) { diff --git a/node/src/main/kotlin/com/r3corda/node/services/events/NodeSchedulerService.kt b/node/src/main/kotlin/com/r3corda/node/services/events/NodeSchedulerService.kt new file mode 100644 index 0000000000..dd6849d942 --- /dev/null +++ b/node/src/main/kotlin/com/r3corda/node/services/events/NodeSchedulerService.kt @@ -0,0 +1,177 @@ +package com.r3corda.node.services.events + +import com.google.common.util.concurrent.SettableFuture +import com.r3corda.core.ThreadBox +import com.r3corda.core.contracts.SchedulableState +import com.r3corda.core.contracts.ScheduledStateRef +import com.r3corda.core.contracts.StateRef +import com.r3corda.core.node.services.SchedulerService +import com.r3corda.core.protocols.ProtocolLogicRefFactory +import com.r3corda.core.serialization.SingletonSerializeAsToken +import com.r3corda.core.utilities.loggerFor +import com.r3corda.core.utilities.trace +import com.r3corda.node.services.api.ServiceHubInternal +import com.r3corda.node.utilities.awaitWithDeadline +import java.time.Instant +import java.util.* +import java.util.concurrent.Executor +import java.util.concurrent.Executors +import javax.annotation.concurrent.ThreadSafe + +/** + * A first pass of a simple [SchedulerService] that works with [MutableClock]s for testing, demonstrations and simulations + * that also encompasses the [Wallet] observer for processing transactions. + * + * This will observe transactions as they are stored and schedule and unschedule activities based on the States consumed + * or produced. + * + * TODO: Needs extensive support from persistence and protocol frameworks to be truly reliable and atomic. + * + * Currently does not provide any system state other than the ContractState so the expectation is that a transaction + * is the outcome of the activity in order to schedule another activity. Once we have implemented more persistence + * in the nodes, maybe we can consider multiple activities and whether the activities have been completed or not, + * but that starts to sound a lot like off-ledger state. + * + * @param services Core node services. + * @param protocolLogicRefFactory Factory for restoring [ProtocolLogic] instances from references. + * @param schedulerTimerExecutor The executor the scheduler blocks on waiting for the clock to advance to the next + * activity. Only replace this for unit testing purposes. This is not the executor the [ProtocolLogic] is launched on. + */ +@ThreadSafe +class NodeSchedulerService(private val services: ServiceHubInternal, + private val protocolLogicRefFactory: ProtocolLogicRefFactory = ProtocolLogicRefFactory(), + private val schedulerTimerExecutor: Executor = Executors.newSingleThreadExecutor()) +: SchedulerService, SingletonSerializeAsToken() { + + private val log = loggerFor() + + // Variables inside InnerState are protected with a lock by the ThreadBox and aren't in scope unless you're + // inside mutex.locked {} code block. So we can't forget to take the lock unless we accidentally leak a reference + // to somewhere. + private class InnerState { + // TODO: This has no persistence, and we don't consider initialising from non-empty map if we add persistence. + // If we were to rebuild the wallet at start up by replaying transactions and re-calculating, then + // persistence here would be unnecessary. + var scheduledStates = HashMap() + var earliestState: ScheduledStateRef? = null + var rescheduled: SettableFuture? = null + + internal fun recomputeEarliest() { + earliestState = scheduledStates.map { it.value }.sortedBy { it.scheduledAt }.firstOrNull() + } + } + + private val mutex = ThreadBox(InnerState()) + + override fun scheduleStateActivity(action: ScheduledStateRef) { + log.trace { "Schedule $action" } + mutex.locked { + scheduledStates[action.ref] = action + if (action.scheduledAt.isBefore(earliestState?.scheduledAt ?: Instant.MAX)) { + // We are earliest + earliestState = action + rescheduleWakeUp() + } else if (earliestState?.ref == action.ref && earliestState!!.scheduledAt != action.scheduledAt) { + // We were earliest but might not be any more + recomputeEarliest() + rescheduleWakeUp() + } + } + } + + override fun unscheduleStateActivity(ref: StateRef) { + log.trace { "Unschedule $ref" } + mutex.locked { + val removedAction = scheduledStates.remove(ref) + if (removedAction == earliestState && removedAction != null) { + recomputeEarliest() + rescheduleWakeUp() + } + } + } + + /** + * This method first cancels the [Future] for any pending action so that the [awaitWithDeadline] used below + * drops through without running the action. We then create a new [Future] for the new action (so it too can be + * cancelled), and then await the arrival of the scheduled time. If we reach the scheduled time (the deadline) + * without the [Future] being cancelled then we run the scheduled action. Finally we remove that action from the + * scheduled actions and recompute the next scheduled action. + */ + private fun rescheduleWakeUp() { + // Note, we already have the mutex but we need the scope again here + val (scheduledState, ourRescheduledFuture) = mutex.alreadyLocked { + rescheduled?.cancel(false) + rescheduled = SettableFuture.create() + Pair(earliestState, rescheduled!!) + } + if (scheduledState != null) { + schedulerTimerExecutor.execute() { + log.trace { "Scheduling as next $scheduledState" } + // This will block the scheduler single thread until the scheduled time (returns false) OR + // the Future is cancelled due to rescheduling (returns true). + if (!services.clock.awaitWithDeadline(scheduledState.scheduledAt, ourRescheduledFuture)) { + log.trace { "Invoking as next $scheduledState" } + onTimeReached(scheduledState) + } else { + log.trace { "Recheduled $scheduledState" } + } + } + } + } + + private fun onTimeReached(scheduledState: ScheduledStateRef) { + try { + runScheduledActionForState(scheduledState) + } finally { + // Unschedule once complete (or checkpointed) + mutex.locked { + // need to remove us from those scheduled, but only if we are still next + scheduledStates.compute(scheduledState.ref) { ref, value -> + if (value === scheduledState) null else value + } + // and schedule the next one + recomputeEarliest() + rescheduleWakeUp() + } + } + } + + private fun runScheduledActionForState(scheduledState: ScheduledStateRef) { + val txState = services.loadState(scheduledState.ref) + // It's OK to return if it's null as there's nothing scheduled + // TODO: implement sandboxing as necessary + val scheduledActivity = sandbox { + val state = txState.data as SchedulableState + state.nextScheduledActivity(scheduledState.ref, protocolLogicRefFactory) + } ?: return + + if (scheduledActivity.scheduledAt.isAfter(services.clock.instant())) { + // I suppose it might turn out that the action is no longer due (a bug, maybe), so we need to defend against that and re-schedule + // TODO: warn etc + mutex.locked { + // Replace with updated instant + scheduledStates.compute(scheduledState.ref) { ref, value -> + if (value === scheduledState) ScheduledStateRef(scheduledState.ref, scheduledActivity.scheduledAt) else value + } + } + } else { + /** + * TODO: align with protocol invocation via API... make it the same code + * TODO: Persistence and durability issues: + * a) Need to consider potential to run activity twice if restart between here and removing from map if we add persistence + * b) But if remove from map first, there's potential to run zero times if restart + * c) Address by switch to 3rd party scheduler? Only benefit of this impl. is support for DemoClock or other MutableClocks (e.g. for testing) + * TODO: ProtocolLogicRefFactory needs to sort out the class loader etc + */ + val logic = protocolLogicRefFactory.toProtocolLogic(scheduledActivity.logicRef) + log.trace { "Firing ProtocolLogic $logic" } + // TODO: ProtocolLogic should be checkpointed by the time this returns + services.startProtocol("scheduled", logic) + } + } + + // TODO: Does nothing right now, but beware we are calling dynamically loaded code in the contract inside here. + private inline fun sandbox(code: () -> T?): T? { + return code() + } +} \ No newline at end of file diff --git a/node/src/main/kotlin/com/r3corda/node/services/events/ScheduledActivityObserver.kt b/node/src/main/kotlin/com/r3corda/node/services/events/ScheduledActivityObserver.kt new file mode 100644 index 0000000000..be75393bed --- /dev/null +++ b/node/src/main/kotlin/com/r3corda/node/services/events/ScheduledActivityObserver.kt @@ -0,0 +1,35 @@ +package com.r3corda.node.services.events + +import com.r3corda.core.contracts.ContractState +import com.r3corda.core.contracts.SchedulableState +import com.r3corda.core.contracts.ScheduledStateRef +import com.r3corda.core.contracts.StateAndRef +import com.r3corda.core.protocols.ProtocolLogicRefFactory +import com.r3corda.node.services.api.ServiceHubInternal + +/** + * This observes the wallet and schedules and unschedules activities appropriately based on state production and + * consumption. + */ +class ScheduledActivityObserver(val services: ServiceHubInternal) { + init { + // TODO: Need to consider failure scenarios. This needs to run if the TX is successfully recorded + services.walletService.updates.subscribe { update -> + update.consumed.forEach { services.schedulerService.unscheduleStateActivity(it) } + update.produced.forEach { scheduleStateActivity(it, services.protocolLogicRefFactory) } + } + } + + private fun scheduleStateActivity(produced: StateAndRef, protocolLogicRefFactory: ProtocolLogicRefFactory) { + val producedState = produced.state.data + if (producedState is SchedulableState) { + val scheduledAt = sandbox { producedState.nextScheduledActivity(produced.ref, protocolLogicRefFactory)?.scheduledAt } ?: return + services.schedulerService.scheduleStateActivity(ScheduledStateRef(produced.ref, scheduledAt)) + } + } + + // TODO: Beware we are calling dynamically loaded contract code inside here. + private inline fun sandbox(code: () -> T?): T? { + return code() + } +} \ No newline at end of file diff --git a/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt b/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt index ede0a51205..ccd6a3545c 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/network/NetworkMapService.kt @@ -7,16 +7,16 @@ import com.r3corda.core.messaging.MessageRecipients import com.r3corda.core.messaging.MessagingService import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.NodeInfo -import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.NetworkMapCache +import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.TOPIC_DEFAULT_POSTFIX import com.r3corda.core.serialization.SerializedBytes import com.r3corda.core.serialization.deserialize import com.r3corda.core.serialization.serialize import com.r3corda.node.services.api.AbstractNodeService import com.r3corda.node.utilities.AddOrRemove +import com.r3corda.protocols.ServiceRequestMessage import org.slf4j.LoggerFactory -import com.r3corda.protocols.AbstractRequestMessage import java.security.PrivateKey import java.security.SignatureException import java.time.Instant @@ -61,20 +61,25 @@ interface NetworkMapService { val nodes: List - class FetchMapRequest(val subscribe: Boolean, val ifChangedSinceVersion: Int?, replyTo: MessageRecipients, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + abstract class NetworkMapRequestMessage(val replyTo: MessageRecipients) : ServiceRequestMessage { + override fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients = replyTo + } + + class FetchMapRequest(val subscribe: Boolean, val ifChangedSinceVersion: Int?, replyTo: MessageRecipients, override val sessionID: Long) : NetworkMapRequestMessage(replyTo) data class FetchMapResponse(val nodes: Collection?, val version: Int) - class QueryIdentityRequest(val identity: Party, replyTo: MessageRecipients, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + class QueryIdentityRequest(val identity: Party, replyTo: MessageRecipients, override val sessionID: Long) : NetworkMapRequestMessage(replyTo) data class QueryIdentityResponse(val node: NodeInfo?) - class RegistrationRequest(val wireReg: WireNodeRegistration, replyTo: MessageRecipients, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + class RegistrationRequest(val wireReg: WireNodeRegistration, replyTo: MessageRecipients, override val sessionID: Long) : NetworkMapRequestMessage(replyTo) data class RegistrationResponse(val success: Boolean) - class SubscribeRequest(val subscribe: Boolean, replyTo: MessageRecipients, sessionID: Long) : AbstractRequestMessage(replyTo, sessionID) + class SubscribeRequest(val subscribe: Boolean, replyTo: MessageRecipients, override val sessionID: Long) : NetworkMapRequestMessage(replyTo) data class SubscribeResponse(val confirmed: Boolean) data class Update(val wireReg: WireNodeRegistration, val replyTo: MessageRecipients) data class UpdateAcknowledge(val wireRegHash: SecureHash, val replyTo: MessageRecipients) } + @ThreadSafe -class InMemoryNetworkMapService(net: MessagingService, home: NodeRegistration, val cache: NetworkMapCache) : NetworkMapService, AbstractNodeService(net) { +class InMemoryNetworkMapService(net: MessagingService, home: NodeRegistration, val cache: NetworkMapCache) : NetworkMapService, AbstractNodeService(net, cache) { private val registeredNodes = ConcurrentHashMap() // Map from subscriber address, to a list of unacknowledged updates private val subscribers = ThreadBox(mutableMapOf>()) diff --git a/node/src/main/kotlin/com/r3corda/node/services/persistence/DataVendingService.kt b/node/src/main/kotlin/com/r3corda/node/services/persistence/DataVendingService.kt index 43a09867ab..1468897f9a 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/persistence/DataVendingService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/persistence/DataVendingService.kt @@ -2,6 +2,7 @@ package com.r3corda.node.services.persistence import com.r3corda.core.contracts.SignedTransaction import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.StorageService import com.r3corda.core.utilities.loggerFor import com.r3corda.node.services.api.AbstractNodeService @@ -24,7 +25,7 @@ import javax.annotation.concurrent.ThreadSafe * Additionally, because nodes do not store invalid transactions, requesting such a transaction will always yield null. */ @ThreadSafe -class DataVendingService(net: MessagingService, private val storage: StorageService) : AbstractNodeService(net) { +class DataVendingService(net: MessagingService, private val storage: StorageService, networkMapCache: NetworkMapCache) : AbstractNodeService(net, networkMapCache) { companion object { val logger = loggerFor() } diff --git a/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt b/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt index 56000f4700..43a5aa98cc 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/statemachine/ProtocolStateMachineImpl.kt @@ -5,7 +5,7 @@ import co.paralleluniverse.fibers.FiberScheduler import co.paralleluniverse.fibers.Suspendable import com.google.common.util.concurrent.ListenableFuture import com.google.common.util.concurrent.SettableFuture -import com.r3corda.core.messaging.MessageRecipients +import com.r3corda.core.crypto.Party import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.protocols.ProtocolStateMachine import com.r3corda.core.utilities.UntrustworthyData @@ -81,9 +81,13 @@ class ProtocolStateMachineImpl(val logic: ProtocolLogic, } @Suspendable @Suppress("UNCHECKED_CAST") - override fun sendAndReceive(topic: String, destination: MessageRecipients, sessionIDForSend: Long, sessionIDForReceive: Long, - obj: Any, recvType: Class): UntrustworthyData { - val result = StateMachineManager.FiberRequest.ExpectingResponse(topic, destination, sessionIDForSend, sessionIDForReceive, obj, recvType) + override fun sendAndReceive(topic: String, + destination: Party, + sessionIDForSend: Long, + sessionIDForReceive: Long, + payload: Any, + recvType: Class): UntrustworthyData { + val result = StateMachineManager.FiberRequest.ExpectingResponse(topic, destination, sessionIDForSend, sessionIDForReceive, payload, recvType) return suspendAndExpectReceive(result) } @@ -94,8 +98,8 @@ class ProtocolStateMachineImpl(val logic: ProtocolLogic, } @Suspendable - override fun send(topic: String, destination: MessageRecipients, sessionID: Long, obj: Any) { - val result = StateMachineManager.FiberRequest.NotExpectingResponse(topic, destination, sessionID, obj) + override fun send(topic: String, destination: Party, sessionID: Long, payload: Any) { + val result = StateMachineManager.FiberRequest.NotExpectingResponse(topic, destination, sessionID, payload) suspend(result) } diff --git a/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt b/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt index 2616585dec..affe832ce1 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/statemachine/StateMachineManager.kt @@ -8,7 +8,7 @@ import com.esotericsoftware.kryo.Kryo import com.google.common.base.Throwables import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.abbreviate -import com.r3corda.core.messaging.MessageRecipients +import com.r3corda.core.crypto.Party import com.r3corda.core.messaging.runOnNextMessage import com.r3corda.core.messaging.send import com.r3corda.core.protocols.ProtocolLogic @@ -253,7 +253,9 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, tokenizableService request.payload?.let { val topic = "${request.topic}.${request.sessionIDForSend}" psm.logger.trace { "Sending message of type ${it.javaClass.name} using topic $topic to ${request.destination} (${it.toString().abbreviate(50)})" } - serviceHub.networkService.send(topic, it, request.destination!!) + val node = serviceHub.networkMapCache.getNodeByLegalName(request.destination!!.name) + requireNotNull(node) { "Don't know about ${request.destination}" } + serviceHub.networkService.send(topic, it, node!!.address) } if (request is FiberRequest.NotExpectingResponse) { // We sent a message, but don't expect a response, so re-enter the continuation to let it keep going. @@ -307,7 +309,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, tokenizableService // TODO: Clean this up open class FiberRequest(val topic: String, - val destination: MessageRecipients?, + val destination: Party?, val sessionIDForSend: Long, val sessionIDForReceive: Long, val payload: Any?) { @@ -317,7 +319,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, tokenizableService class ExpectingResponse( topic: String, - destination: MessageRecipients?, + destination: Party?, sessionIDForSend: Long, sessionIDForReceive: Long, obj: Any?, @@ -326,7 +328,7 @@ class StateMachineManager(val serviceHub: ServiceHubInternal, tokenizableService class NotExpectingResponse( topic: String, - destination: MessageRecipients, + destination: Party, sessionIDForSend: Long, obj: Any? ) : FiberRequest(topic, destination, sessionIDForSend, -1, obj) diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt index c549734ad0..6287861bac 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/NotaryService.kt @@ -2,7 +2,7 @@ package com.r3corda.node.services.transactions import com.r3corda.core.messaging.Ack import com.r3corda.core.messaging.MessagingService -import com.r3corda.core.messaging.SingleMessageRecipient +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.TimestampChecker import com.r3corda.core.node.services.UniquenessProvider @@ -22,7 +22,8 @@ import com.r3corda.protocols.NotaryProtocol abstract class NotaryService(val smm: StateMachineManager, net: MessagingService, val timestampChecker: TimestampChecker, - val uniquenessProvider: UniquenessProvider) : AbstractNodeService(net) { + val uniquenessProvider: UniquenessProvider, + networkMapCache: NetworkMapCache) : AbstractNodeService(net, networkMapCache) { object Type : ServiceType("corda.notary") abstract val logger: org.slf4j.Logger @@ -31,14 +32,15 @@ abstract class NotaryService(val smm: StateMachineManager, abstract val protocolFactory: NotaryProtocol.Factory init { - addMessageHandler(NotaryProtocol.TOPIC_INITIATE, + addMessageHandler(NotaryProtocol.TOPIC, { req: NotaryProtocol.Handshake -> processRequest(req) } ) } private fun processRequest(req: NotaryProtocol.Handshake): Ack { - val protocol = protocolFactory.create(req.replyTo as SingleMessageRecipient, - req.sessionID!!, + val protocol = protocolFactory.create( + req.replyToParty, + req.sessionID, req.sendSessionID, timestampChecker, uniquenessProvider) diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt index 850d84d40f..3cf38589f8 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/SimpleNotaryService.kt @@ -1,6 +1,7 @@ package com.r3corda.node.services.transactions import com.r3corda.core.messaging.MessagingService +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.TimestampChecker import com.r3corda.core.node.services.UniquenessProvider @@ -13,7 +14,8 @@ class SimpleNotaryService( smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, - uniquenessProvider: UniquenessProvider) : NotaryService(smm, net, timestampChecker, uniquenessProvider) { + uniquenessProvider: UniquenessProvider, + networkMapCache: NetworkMapCache) : NotaryService(smm, net, timestampChecker, uniquenessProvider, networkMapCache) { object Type : ServiceType("corda.notary.simple") override val logger = loggerFor() diff --git a/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt b/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt index 3b0fc6faf1..d6f8fac88a 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/transactions/ValidatingNotaryService.kt @@ -1,7 +1,8 @@ package com.r3corda.node.services.transactions +import com.r3corda.core.crypto.Party import com.r3corda.core.messaging.MessagingService -import com.r3corda.core.messaging.SingleMessageRecipient +import com.r3corda.core.node.services.NetworkMapCache import com.r3corda.core.node.services.ServiceType import com.r3corda.core.node.services.TimestampChecker import com.r3corda.core.node.services.UniquenessProvider @@ -15,14 +16,15 @@ class ValidatingNotaryService( smm: StateMachineManager, net: MessagingService, timestampChecker: TimestampChecker, - uniquenessProvider: UniquenessProvider -) : NotaryService(smm, net, timestampChecker, uniquenessProvider) { + uniquenessProvider: UniquenessProvider, + networkMapCache: NetworkMapCache +) : NotaryService(smm, net, timestampChecker, uniquenessProvider, networkMapCache) { object Type : ServiceType("corda.notary.validating") override val logger = loggerFor() override val protocolFactory = object : NotaryProtocol.Factory { - override fun create(otherSide: SingleMessageRecipient, + override fun create(otherSide: Party, sendSessionID: Long, receiveSessionID: Long, timestampChecker: TimestampChecker, diff --git a/node/src/main/kotlin/com/r3corda/node/services/wallet/CashBalanceAsMetricsObserver.kt b/node/src/main/kotlin/com/r3corda/node/services/wallet/CashBalanceAsMetricsObserver.kt index 8f0df76574..336b962569 100644 --- a/node/src/main/kotlin/com/r3corda/node/services/wallet/CashBalanceAsMetricsObserver.kt +++ b/node/src/main/kotlin/com/r3corda/node/services/wallet/CashBalanceAsMetricsObserver.kt @@ -1,7 +1,7 @@ package com.r3corda.node.services.wallet import com.codahale.metrics.Gauge -import com.r3corda.contracts.cash.cashBalances +import com.r3corda.contracts.asset.cashBalances import com.r3corda.core.node.services.Wallet import com.r3corda.node.services.api.ServiceHubInternal import java.util.* diff --git a/node/src/main/kotlin/com/r3corda/node/servlets/DataUploadServlet.kt b/node/src/main/kotlin/com/r3corda/node/servlets/DataUploadServlet.kt index e8551d2b98..742061b22d 100644 --- a/node/src/main/kotlin/com/r3corda/node/servlets/DataUploadServlet.kt +++ b/node/src/main/kotlin/com/r3corda/node/servlets/DataUploadServlet.kt @@ -35,6 +35,12 @@ class DataUploadServlet : HttpServlet() { val upload = ServletFileUpload() val iterator = upload.getItemIterator(req) val messages = ArrayList() + + if (!iterator.hasNext()) { + resp.sendError(HttpServletResponse.SC_BAD_REQUEST, "Got an upload request with no files") + return + } + while (iterator.hasNext()) { val item = iterator.next() if (item.name != null && !acceptor.acceptableFileExtensions.any { item.name.endsWith(it) }) { diff --git a/node/src/main/kotlin/com/r3corda/node/utilities/JsonSupport.kt b/node/src/main/kotlin/com/r3corda/node/utilities/JsonSupport.kt index f598f1c17f..3c38165696 100644 --- a/node/src/main/kotlin/com/r3corda/node/utilities/JsonSupport.kt +++ b/node/src/main/kotlin/com/r3corda/node/utilities/JsonSupport.kt @@ -73,7 +73,7 @@ object JsonSupport { return try { LocalDate.parse(parser.text) } catch (e: Exception) { - throw JsonParseException("Invalid LocalDate ${parser.text}: ${e.message}", parser.currentLocation) + throw JsonParseException(parser, "Invalid LocalDate ${parser.text}: ${e.message}") } } } @@ -98,7 +98,7 @@ object JsonSupport { } val mapper = parser.codec as ServiceHubObjectMapper // TODO this needs to use some industry identifier(s) not just these human readable names - return mapper.identities.partyFromName(parser.text) ?: throw JsonParseException("Could not find a Party with name: ${parser.text}", parser.currentLocation) + return mapper.identities.partyFromName(parser.text) ?: throw JsonParseException(parser, "Could not find a Party with name: ${parser.text}") } } @@ -120,7 +120,7 @@ object JsonSupport { @Suppress("UNCHECKED_CAST") return SecureHash.parse(parser.text) as T } catch (e: Exception) { - throw JsonParseException("Invalid hash ${parser.text}: ${e.message}", parser.currentLocation) + throw JsonParseException(parser, "Invalid hash ${parser.text}: ${e.message}") } } } @@ -131,7 +131,7 @@ object JsonSupport { val array = StringArrayDeserializer.instance.deserialize(parser, context) BusinessCalendar.getInstance(*array) } catch (e: Exception) { - throw JsonParseException("Invalid calendar(s) ${parser.text}: ${e.message}", parser.currentLocation) + throw JsonParseException(parser, "Invalid calendar(s) ${parser.text}: ${e.message}") } } } @@ -151,7 +151,7 @@ object JsonSupport { val A = Base58.decode(parser.text) EdDSAPublicKey(EdDSAPublicKeySpec(A, ed25519Curve)) } catch (e: Exception) { - throw JsonParseException("Invalid public key ${parser.text}: ${e.message}", parser.currentLocation) + throw JsonParseException(parser, "Invalid public key ${parser.text}: ${e.message}") } } } diff --git a/node/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry b/node/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry new file mode 100644 index 0000000000..6c27482af8 --- /dev/null +++ b/node/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry @@ -0,0 +1,2 @@ +# Register a ServiceLoader service extending from com.r3corda.node.CordaPluginRegistry +com.r3corda.node.services.clientapi.NodeInterestRates$Service$FixingServicePlugin \ No newline at end of file diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt index b38dc92be6..eddd1f3f94 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/AttachmentTests.kt @@ -59,7 +59,8 @@ class AttachmentTests { val id = n0.storage.attachments.importAttachment(ByteArrayInputStream(fakeAttachment())) // Get node one to run a protocol to fetch it and insert it. - val f1 = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.net.myAddress)) + network.runNetwork() + val f1 = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)) network.runNetwork() assertEquals(0, f1.get().fromDisk.size) @@ -70,7 +71,7 @@ class AttachmentTests { // Shut down node zero and ensure node one can still resolve the attachment. n0.stop() - val response: FetchDataProtocol.Result = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.net.myAddress)).get() + val response: FetchDataProtocol.Result = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)).get() assertEquals(attachment, response.fromDisk[0]) } @@ -80,14 +81,15 @@ class AttachmentTests { // Get node one to fetch a non-existent attachment. val hash = SecureHash.randomSHA256() - val f1 = n1.smm.add("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.net.myAddress)) + network.runNetwork() + val f1 = n1.smm.add("tests.fetch2", FetchAttachmentsProtocol(setOf(hash), n0.info.identity)) network.runNetwork() val e = assertFailsWith { rootCauseExceptions { f1.get() } } assertEquals(hash, e.requested) } @Test - fun maliciousResponse() { + fun `malicious response`() { // Make a node that doesn't do sanity checking at load time. val n0 = network.createNode(null, -1, object : MockNetwork.Factory { override fun create(dir: Path, config: NodeConfiguration, network: MockNetwork, networkMapAddr: NodeInfo?, @@ -112,7 +114,8 @@ class AttachmentTests { writer.close() // Get n1 to fetch the attachment. Should receive corrupted bytes. - val f1 = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.net.myAddress)) + network.runNetwork() + val f1 = n1.smm.add("tests.fetch1", FetchAttachmentsProtocol(setOf(id), n0.info.identity)) network.runNetwork() assertFailsWith { rootCauseExceptions { f1.get() } diff --git a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt index 7975972f8b..0176a6eda9 100644 --- a/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/messaging/TwoPartyTradeProtocolTests.kt @@ -2,7 +2,7 @@ package com.r3corda.node.messaging import com.google.common.util.concurrent.ListenableFuture import com.r3corda.contracts.CommercialPaper -import com.r3corda.contracts.cash.Cash +import com.r3corda.contracts.asset.Cash import com.r3corda.contracts.testing.CASH import com.r3corda.contracts.testing.`issued by` import com.r3corda.contracts.testing.`owned by` @@ -11,7 +11,6 @@ import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.SecureHash import com.r3corda.core.days -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.ServiceHub import com.r3corda.core.node.services.ServiceType @@ -56,17 +55,17 @@ class TwoPartyTradeProtocolTests { lateinit var net: MockNetwork private fun runSeller(smm: StateMachineManager, notary: NodeInfo, - otherSide: SingleMessageRecipient, assetToSell: StateAndRef, price: Amount>, + otherSide: Party, assetToSell: StateAndRef, price: Amount>, myKeyPair: KeyPair, buyerSessionID: Long): ListenableFuture { val seller = TwoPartyTradeProtocol.Seller(otherSide, notary, assetToSell, price, myKeyPair, buyerSessionID) - return smm.add("${TwoPartyTradeProtocol.TRADE_TOPIC}.seller", seller) + return smm.add("${TwoPartyTradeProtocol.TOPIC}.seller", seller) } private fun runBuyer(smm: StateMachineManager, notaryNode: NodeInfo, - otherSide: SingleMessageRecipient, acceptablePrice: Amount>, typeToBuy: Class, + otherSide: Party, acceptablePrice: Amount>, typeToBuy: Class, sessionID: Long): ListenableFuture { val buyer = TwoPartyTradeProtocol.Buyer(otherSide, notaryNode.identity, acceptablePrice, typeToBuy, sessionID) - return smm.add("${TwoPartyTradeProtocol.TRADE_TOPIC}.buyer", buyer) + return smm.add("${TwoPartyTradeProtocol.TOPIC}.buyer", buyer) } @Before @@ -87,7 +86,9 @@ class TwoPartyTradeProtocolTests { // we run in the unit test thread exclusively to speed things up, ensure deterministic results and // allow interruption half way through. net = MockNetwork(false, true) - transactionGroupFor { + + ledger { + val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY) val bobNode = net.createPartyNode(notaryNode.info, BOB.name, BOB_KEY) @@ -105,7 +106,7 @@ class TwoPartyTradeProtocolTests { val bobResult = runBuyer( bobNode.smm, notaryNode.info, - aliceNode.net.myAddress, + aliceNode.info.identity, 1000.DOLLARS `issued by` issuer, CommercialPaper.State::class.java, buyerSessionID @@ -113,8 +114,8 @@ class TwoPartyTradeProtocolTests { val aliceResult = runSeller( aliceNode.smm, notaryNode.info, - bobNode.net.myAddress, - lookup("alice's paper"), + bobNode.info.identity, + "alice's paper".outputStateAndRef(), 1000.DOLLARS `issued by` issuer, ALICE_KEY, buyerSessionID @@ -134,12 +135,12 @@ class TwoPartyTradeProtocolTests { @Test fun `shutdown and restore`() { - transactionGroupFor { + + ledger { val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY) var bobNode = net.createPartyNode(notaryNode.info, BOB.name, BOB_KEY) - val aliceAddr = aliceNode.net.myAddress val bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.Handle val networkMapAddr = notaryNode.info val issuer = bobNode.services.storageService.myLegalIdentity.ref(0) @@ -156,8 +157,8 @@ class TwoPartyTradeProtocolTests { val aliceFuture = runSeller( aliceNode.smm, notaryNode.info, - bobAddr, - lookup("alice's paper"), + bobNode.info.identity, + "alice's paper".outputStateAndRef(), 1000.DOLLARS `issued by` issuer, ALICE_KEY, buyerSessionID @@ -165,7 +166,7 @@ class TwoPartyTradeProtocolTests { runBuyer( bobNode.smm, notaryNode.info, - aliceAddr, + aliceNode.info.identity, 1000.DOLLARS `issued by` issuer, CommercialPaper.State::class.java, buyerSessionID @@ -248,10 +249,11 @@ class TwoPartyTradeProtocolTests { @Test fun `check dependencies of sale asset are resolved`() { - transactionGroupFor { - val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) - val aliceNode = makeNodeWithTracking(notaryNode.info, ALICE.name, ALICE_KEY) - val bobNode = makeNodeWithTracking(notaryNode.info, BOB.name, BOB_KEY) + val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) + val aliceNode = makeNodeWithTracking(notaryNode.info, ALICE.name, ALICE_KEY) + val bobNode = makeNodeWithTracking(notaryNode.info, BOB.name, BOB_KEY) + + ledger(storageService = aliceNode.storage) { // Insert a prospectus type attachment into the commercial paper transaction. val stream = ByteArrayOutputStream() @@ -260,7 +262,7 @@ class TwoPartyTradeProtocolTests { it.write("Our commercial paper is top notch stuff".toByteArray()) it.closeEntry() } - val attachmentID = aliceNode.storage.attachments.importAttachment(ByteArrayInputStream(stream.toByteArray())) + val attachmentID = attachment(ByteArrayInputStream(stream.toByteArray())) val issuer = MEGA_CORP.ref(1) val bobsFakeCash = fillUpForBuyer(false, bobNode.keyManagement.freshKey().public, issuer).second @@ -276,8 +278,8 @@ class TwoPartyTradeProtocolTests { runSeller( aliceNode.smm, notaryNode.info, - bobNode.net.myAddress, - lookup("alice's paper"), + bobNode.info.identity, + "alice's paper".outputStateAndRef(), 1000.DOLLARS `issued by` issuer, ALICE_KEY, buyerSessionID @@ -285,7 +287,7 @@ class TwoPartyTradeProtocolTests { runBuyer( bobNode.smm, notaryNode.info, - aliceNode.net.myAddress, + aliceNode.info.identity, 1000.DOLLARS `issued by` issuer, CommercialPaper.State::class.java, buyerSessionID @@ -352,28 +354,28 @@ class TwoPartyTradeProtocolTests { @Test fun `dependency with error on buyer side`() { - transactionGroupFor { + ledger { runWithError(true, false, "at least one asset input") } } @Test fun `dependency with error on seller side`() { - transactionGroupFor { + ledger { runWithError(false, true, "must be timestamped") } } - private fun TransactionGroupDSL.runWithError(bobError: Boolean, aliceError: Boolean, - expectedMessageSubstring: String) { + private fun LedgerDSL.runWithError( + bobError: Boolean, + aliceError: Boolean, + expectedMessageSubstring: String + ) { val notaryNode = net.createNotaryNode(DUMMY_NOTARY.name, DUMMY_NOTARY_KEY) val aliceNode = net.createPartyNode(notaryNode.info, ALICE.name, ALICE_KEY) val bobNode = net.createPartyNode(notaryNode.info, BOB.name, BOB_KEY) val issuer = MEGA_CORP.ref(1, 2, 3) - val aliceAddr = aliceNode.net.myAddress - val bobAddr = bobNode.net.myAddress as InMemoryMessagingNetwork.Handle - val bobKey = bobNode.keyManagement.freshKey() val bobsBadCash = fillUpForBuyer(bobError, bobKey.public).second val alicesFakePaper = fillUpForSeller(aliceError, aliceNode.storage.myLegalIdentity.owningKey, @@ -389,8 +391,8 @@ class TwoPartyTradeProtocolTests { val aliceResult = runSeller( aliceNode.smm, notaryNode.info, - bobAddr, - lookup("alice's paper"), + bobNode.info.identity, + "alice's paper".outputStateAndRef(), 1000.DOLLARS `issued by` issuer, ALICE_KEY, buyerSessionID @@ -398,7 +400,7 @@ class TwoPartyTradeProtocolTests { val bobResult = runBuyer( bobNode.smm, notaryNode.info, - aliceAddr, + aliceNode.info.identity, 1000.DOLLARS `issued by` issuer, CommercialPaper.State::class.java, buyerSessionID @@ -416,10 +418,11 @@ class TwoPartyTradeProtocolTests { assertTrue(e.cause!!.cause!!.message!!.contains(expectedMessageSubstring)) } - private fun TransactionGroupDSL.insertFakeTransactions(wtxToSign: List, - services: ServiceHub, - vararg extraKeys: KeyPair): Map { - val signed: List = signAll(wtxToSign, *extraKeys) + private fun insertFakeTransactions( + wtxToSign: List, + services: ServiceHub, + vararg extraKeys: KeyPair): Map { + val signed: List = signAll(wtxToSign, extraKeys) services.recordTransactions(signed) val validatedTransactions = services.storageService.validatedTransactions if (validatedTransactions is RecordingTransactionStorage) { @@ -428,9 +431,10 @@ class TwoPartyTradeProtocolTests { return signed.associateBy { it.id } } - private fun TransactionGroupDSL.fillUpForBuyer(withError: Boolean, - owner: PublicKey = BOB_PUBKEY, - issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair> { + private fun LedgerDSL.fillUpForBuyer( + withError: Boolean, + owner: PublicKey = BOB_PUBKEY, + issuer: PartyAndReference = MEGA_CORP.ref(1)): Pair> { // Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she // wants to sell to Bob. @@ -439,52 +443,64 @@ class TwoPartyTradeProtocolTests { output("elbonian money 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } output("elbonian money 2") { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } if (!withError) - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } + command(MEGA_CORP_PUBKEY) { Cash.Commands.Issue() } timestamp(TEST_TX_TIME) + if (withError) { + this.fails() + } else { + this.verifies() + } } // Bob gets some cash onto the ledger from BoE val bc1 = transaction { input("elbonian money 1") output("bob cash 1") { 800.DOLLARS.CASH `issued by` issuer `owned by` owner } - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + this.verifies() } val bc2 = transaction { input("elbonian money 2") output("bob cash 2") { 300.DOLLARS.CASH `issued by` issuer `owned by` owner } output { 700.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY } // Change output. - arg(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + command(MEGA_CORP_PUBKEY) { Cash.Commands.Move() } + this.verifies() } - val wallet = Wallet(listOf>(lookup("bob cash 1"), lookup("bob cash 2"))) + val wallet = Wallet(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef())) return Pair(wallet, listOf(eb1, bc1, bc2)) } - private fun TransactionGroupDSL.fillUpForSeller(withError: Boolean, - owner: PublicKey, - amount: Amount>, - notary: Party, - attachmentID: SecureHash?): Pair> { + private fun LedgerDSL.fillUpForSeller( + withError: Boolean, + owner: PublicKey, + amount: Amount>, + notary: Party, + attachmentID: SecureHash?): Pair> { val ap = transaction { output("alice's paper") { CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days) } - arg(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() } + command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() } if (!withError) - arg(notary.owningKey) { TimestampCommand(TEST_TX_TIME, 30.seconds) } + command(notary.owningKey) { TimestampCommand(TEST_TX_TIME, 30.seconds) } if (attachmentID != null) attachment(attachmentID) + if (withError) { + this.fails() + } else { + this.verifies() + } } - val wallet = Wallet(listOf>(lookup("alice's paper"))) + val wallet = Wallet(listOf("alice's paper".outputStateAndRef())) return Pair(wallet, listOf(ap)) } - class RecordingTransactionStorage(val delegate: TransactionStorage) : TransactionStorage { - val records = Collections.synchronizedList(ArrayList()) + val records: MutableList = Collections.synchronizedList(ArrayList()) override fun addTransaction(transaction: SignedTransaction) { records.add(TxRecord.Add(transaction)) diff --git a/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt b/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt index cbfabb5bfe..5f55b8906e 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/InMemoryNetworkMapServiceTest.kt @@ -59,7 +59,7 @@ class InMemoryNetworkMapServiceTest { assertEquals(2, service.nodes.count()) // Confirm that de-registering the node succeeds and drops it from the node lists - var removeChange = NodeRegistration(registerNode.info, seq, AddOrRemove.REMOVE, expires) + val removeChange = NodeRegistration(registerNode.info, seq, AddOrRemove.REMOVE, expires) val removeWireChange = removeChange.toWire(nodeKey.private) assert(service.processRegistrationChangeRequest(NetworkMapService.RegistrationRequest(removeWireChange, mapServiceNode.info.address, Long.MIN_VALUE)).success) assertNull(service.processQueryRequest(NetworkMapService.QueryIdentityRequest(registerNode.info.identity, mapServiceNode.info.address, Long.MIN_VALUE)).node) @@ -68,61 +68,57 @@ class InMemoryNetworkMapServiceTest { assert(!service.processRegistrationChangeRequest(NetworkMapService.RegistrationRequest(removeWireChange, mapServiceNode.info.address, Long.MIN_VALUE)).success) } - class TestAcknowledgePSM(val server: NodeInfo, val hash: SecureHash) - : ProtocolLogic() { + class TestAcknowledgePSM(val server: NodeInfo, val hash: SecureHash) : ProtocolLogic() { + override val topic: String get() = NetworkMapService.PUSH_ACK_PROTOCOL_TOPIC @Suspendable override fun call() { val req = NetworkMapService.UpdateAcknowledge(hash, serviceHub.networkService.myAddress) - send(NetworkMapService.PUSH_ACK_PROTOCOL_TOPIC, server.address, 0, req) + send(server.identity, 0, req) } } class TestFetchPSM(val server: NodeInfo, val subscribe: Boolean, val ifChangedSinceVersion: Int? = null) : ProtocolLogic?>() { + override val topic: String get() = NetworkMapService.FETCH_PROTOCOL_TOPIC @Suspendable override fun call(): Collection? { val sessionID = random63BitValue() val req = NetworkMapService.FetchMapRequest(subscribe, ifChangedSinceVersion, serviceHub.networkService.myAddress, sessionID) - return sendAndReceive( - NetworkMapService.FETCH_PROTOCOL_TOPIC, server.address, 0, sessionID, req) - .validate { it.nodes } + return sendAndReceive(server.identity, 0, sessionID, req).validate { it.nodes } } } class TestRegisterPSM(val server: NodeInfo, val reg: NodeRegistration, val privateKey: PrivateKey) : ProtocolLogic() { + override val topic: String get() = NetworkMapService.REGISTER_PROTOCOL_TOPIC @Suspendable override fun call(): NetworkMapService.RegistrationResponse { val sessionID = random63BitValue() val req = NetworkMapService.RegistrationRequest(reg.toWire(privateKey), serviceHub.networkService.myAddress, sessionID) - - return sendAndReceive( - NetworkMapService.REGISTER_PROTOCOL_TOPIC, server.address, 0, sessionID, req) - .validate { it } + return sendAndReceive(server.identity, 0, sessionID, req).validate { it } } } class TestSubscribePSM(val server: NodeInfo, val subscribe: Boolean) : ProtocolLogic() { + override val topic: String get() = NetworkMapService.SUBSCRIPTION_PROTOCOL_TOPIC @Suspendable override fun call(): NetworkMapService.SubscribeResponse { val sessionID = random63BitValue() val req = NetworkMapService.SubscribeRequest(subscribe, serviceHub.networkService.myAddress, sessionID) - - return sendAndReceive( - NetworkMapService.SUBSCRIPTION_PROTOCOL_TOPIC, server.address, 0, sessionID, req) - .validate { it } + return sendAndReceive(server.identity, 0, sessionID, req).validate { it } } } @Test - fun successWithNetwork() { + fun `success with network`() { val (mapServiceNode, registerNode) = network.createTwoNodes() // Confirm there's a network map service on node 0 assertNotNull(mapServiceNode.inNodeNetworkMapService) // Confirm all nodes have registered themselves + network.runNetwork() var fetchPsm = registerNode.smm.add(NetworkMapService.FETCH_PROTOCOL_TOPIC, TestFetchPSM(mapServiceNode.info, false)) network.runNetwork() assertEquals(2, fetchPsm.get()?.count()) @@ -143,11 +139,12 @@ class InMemoryNetworkMapServiceTest { } @Test - fun subscribeWithNetwork() { + fun `subscribe with network`() { val (mapServiceNode, registerNode) = network.createTwoNodes() val service = (mapServiceNode.inNodeNetworkMapService as InMemoryNetworkMapService) // Test subscribing to updates + network.runNetwork() val subscribePsm = registerNode.smm.add(NetworkMapService.SUBSCRIPTION_PROTOCOL_TOPIC, TestSubscribePSM(mapServiceNode.info, true)) network.runNetwork() diff --git a/node/src/test/kotlin/com/r3corda/node/services/MockServices.kt b/node/src/test/kotlin/com/r3corda/node/services/MockServices.kt index b600350ad8..242d41dbf2 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/MockServices.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/MockServices.kt @@ -1,10 +1,13 @@ package com.r3corda.node.services import com.codahale.metrics.MetricRegistry +import com.google.common.util.concurrent.ListenableFuture import com.r3corda.core.contracts.SignedTransaction import com.r3corda.core.messaging.MessagingService import com.r3corda.core.node.services.* import com.r3corda.core.node.services.testing.MockStorageService +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.protocols.ProtocolLogicRefFactory import com.r3corda.core.testing.MOCK_IDENTITY_SERVICE import com.r3corda.node.serialization.NodeClock import com.r3corda.node.services.api.MonitoringService @@ -12,6 +15,7 @@ import com.r3corda.node.services.api.ServiceHubInternal import com.r3corda.node.services.network.MockNetworkMapCache import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.persistence.DataVendingService +import com.r3corda.node.services.statemachine.StateMachineManager import com.r3corda.node.services.wallet.NodeWalletService import java.time.Clock @@ -23,10 +27,11 @@ open class MockServices( val storage: TxWritableStorageService? = MockStorageService(), val mapCache: NetworkMapCache? = MockNetworkMapCache(), val mapService: NetworkMapService? = null, - val overrideClock: Clock? = NodeClock() + val scheduler: SchedulerService? = null, + val overrideClock: Clock? = NodeClock(), + val protocolFactory: ProtocolLogicRefFactory? = ProtocolLogicRefFactory() ) : ServiceHubInternal() { override val walletService: WalletService = customWallet ?: NodeWalletService(this) - override val keyManagementService: KeyManagementService get() = keyManagement ?: throw UnsupportedOperationException() override val identityService: IdentityService @@ -37,10 +42,15 @@ open class MockServices( get() = mapCache ?: throw UnsupportedOperationException() override val storageService: StorageService get() = storage ?: throw UnsupportedOperationException() + override val schedulerService: SchedulerService + get() = scheduler ?: throw UnsupportedOperationException() override val clock: Clock get() = overrideClock ?: throw UnsupportedOperationException() override val monitoringService: MonitoringService = MonitoringService(MetricRegistry()) + override val protocolLogicRefFactory: ProtocolLogicRefFactory + get() = protocolFactory ?: throw UnsupportedOperationException() + // We isolate the storage service with writable TXes so that it can't be accessed except via recordTransactions() private val txStorageService: TxWritableStorageService get() = storage ?: throw UnsupportedOperationException() @@ -48,11 +58,17 @@ open class MockServices( override fun recordTransactions(txs: Iterable) = recordTransactionsInternal(txStorageService, txs) + lateinit var smm: StateMachineManager + + override fun startProtocol(loggerName: String, logic: ProtocolLogic): ListenableFuture { + return smm.add(loggerName, logic) + } + init { if (net != null && storage != null) { // Creating this class is sufficient, we don't have to store it anywhere, because it registers a listener // on the networking service, so that will keep it from being collected. - DataVendingService(net, storage) + DataVendingService(net, storage, networkMapCache) } } } diff --git a/node/src/test/kotlin/com/r3corda/node/services/NodeInterestRatesTest.kt b/node/src/test/kotlin/com/r3corda/node/services/NodeInterestRatesTest.kt index 4062170da1..3e25f4326c 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/NodeInterestRatesTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/NodeInterestRatesTest.kt @@ -1,6 +1,6 @@ package com.r3corda.node.services -import com.r3corda.contracts.cash.Cash +import com.r3corda.contracts.asset.Cash import com.r3corda.contracts.testing.CASH import com.r3corda.contracts.testing.`issued by` import com.r3corda.contracts.testing.`owned by` @@ -8,9 +8,9 @@ import com.r3corda.contracts.testing.`with notary` import com.r3corda.core.bd import com.r3corda.core.contracts.DOLLARS import com.r3corda.core.contracts.Fix +import com.r3corda.core.contracts.TransactionType import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.generateKeyPair -import com.r3corda.core.contracts.TransactionType import com.r3corda.core.testing.ALICE_PUBKEY import com.r3corda.core.testing.DUMMY_NOTARY import com.r3corda.core.testing.MEGA_CORP @@ -21,6 +21,8 @@ import com.r3corda.node.services.clientapi.NodeInterestRates import com.r3corda.protocols.RatesFixProtocol import org.junit.Assert import org.junit.Test +import java.time.Clock +import java.time.Duration import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -37,11 +39,12 @@ class NodeInterestRatesTest { val DUMMY_CASH_ISSUER_KEY = generateKeyPair() val DUMMY_CASH_ISSUER = Party("Cash issuer", DUMMY_CASH_ISSUER_KEY.public) - val oracle = NodeInterestRates.Oracle(MEGA_CORP, MEGA_CORP_KEY).apply { knownFixes = TEST_DATA } + val clock = Clock.systemUTC() + val oracle = NodeInterestRates.Oracle(MEGA_CORP, MEGA_CORP_KEY, clock).apply { knownFixes = TEST_DATA } @Test fun `query successfully`() { val q = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") - val res = oracle.query(listOf(q)) + val res = oracle.query(listOf(q), clock.instant()) assertEquals(1, res.size) assertEquals("0.678".bd, res[0].value) assertEquals(q, res[0].of) @@ -50,13 +53,13 @@ class NodeInterestRatesTest { @Test fun `query with one success and one missing`() { val q1 = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") val q2 = NodeInterestRates.parseFixOf("LIBOR 2016-03-15 1M") - val e = assertFailsWith { oracle.query(listOf(q1, q2)) } + val e = assertFailsWith { oracle.query(listOf(q1, q2), clock.instant()) } assertEquals(e.fix, q2) } @Test fun `query successfully with interpolated rate`() { val q = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 5M") - val res = oracle.query(listOf(q)) + val res = oracle.query(listOf(q), clock.instant()) assertEquals(1, res.size) Assert.assertEquals(0.7316228, res[0].value.toDouble(), 0.0000001) assertEquals(q, res[0].of) @@ -64,11 +67,11 @@ class NodeInterestRatesTest { @Test fun `rate missing and unable to interpolate`() { val q = NodeInterestRates.parseFixOf("EURIBOR 2016-03-15 3M") - assertFailsWith { oracle.query(listOf(q)) } + assertFailsWith { oracle.query(listOf(q), clock.instant()) } } @Test fun `empty query`() { - assertFailsWith { oracle.query(emptyList()) } + assertFailsWith { oracle.query(emptyList(), clock.instant()) } } @Test fun `refuse to sign with no relevant commands`() { @@ -80,7 +83,7 @@ class NodeInterestRatesTest { @Test fun `sign successfully`() { val tx = makeTX() - val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M"))).first() + val fix = oracle.query(listOf(NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")), clock.instant()).first() tx.addCommand(fix, oracle.identity.owningKey) // Sign successfully. @@ -106,8 +109,9 @@ class NodeInterestRatesTest { val tx = TransactionType.General.Builder() val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M") - val protocol = RatesFixProtocol(tx, n2.info, fixOf, "0.675".bd, "0.1".bd) + val protocol = RatesFixProtocol(tx, n2.info.identity, fixOf, "0.675".bd, "0.1".bd, Duration.ofNanos(1)) BriefLogFormatter.initVerbose("rates") + net.runNetwork() val future = n1.smm.add("rates", protocol) net.runNetwork() @@ -120,4 +124,4 @@ class NodeInterestRatesTest { } private fun makeTX() = TransactionType.General.Builder().withItems(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY) -} \ No newline at end of file +} diff --git a/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt b/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt new file mode 100644 index 0000000000..c2f20ec8b3 --- /dev/null +++ b/node/src/test/kotlin/com/r3corda/node/services/NodeSchedulerServiceTest.kt @@ -0,0 +1,248 @@ +package com.r3corda.node.services + +import com.google.common.jimfs.Configuration +import com.google.common.jimfs.Jimfs +import com.r3corda.core.contracts.* +import com.r3corda.core.crypto.SecureHash +import com.r3corda.core.days +import com.r3corda.core.node.ServiceHub +import com.r3corda.core.node.services.testing.MockKeyManagementService +import com.r3corda.core.protocols.ProtocolLogic +import com.r3corda.core.protocols.ProtocolLogicRef +import com.r3corda.core.protocols.ProtocolLogicRefFactory +import com.r3corda.core.serialization.SingletonSerializeAsToken +import com.r3corda.core.testing.ALICE_KEY +import com.r3corda.core.testing.DUMMY_NOTARY +import com.r3corda.node.internal.testing.TestClock +import com.r3corda.node.services.events.NodeSchedulerService +import com.r3corda.node.services.network.InMemoryMessagingNetwork +import com.r3corda.node.services.persistence.PerFileCheckpointStorage +import com.r3corda.node.services.statemachine.StateMachineManager +import com.r3corda.node.utilities.AffinityExecutor +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import java.nio.file.FileSystem +import java.security.PublicKey +import java.time.Clock +import java.time.Instant +import java.util.concurrent.CountDownLatch +import java.util.concurrent.Executors +import java.util.concurrent.TimeUnit + +class NodeSchedulerServiceTest : SingletonSerializeAsToken() { + // Use an in memory file system for testing attachment storage. + val fs: FileSystem = Jimfs.newFileSystem(Configuration.unix()) + + val realClock: Clock = Clock.systemUTC() + val stoppedClock = Clock.fixed(realClock.instant(), realClock.zone) + val testClock = TestClock(stoppedClock) + + val smmExecutor = AffinityExecutor.ServiceAffinityExecutor("test", 1) + val schedulerGatedExecutor = AffinityExecutor.Gate(true) + + // We have to allow Java boxed primitives but Kotlin warns we shouldn't be using them + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + val factory = ProtocolLogicRefFactory(mapOf(Pair(TestProtocolLogic::class.java.name, setOf(NodeSchedulerServiceTest::class.java.name, Integer::class.java.name)))) + + val scheduler: NodeSchedulerService + val services: ServiceHub + + /** + * Have a reference to this test added to [ServiceHub] so that when the [ProtocolLogic] runs it can access the test instance. + * The [TestState] is serialized and deserialized so attempting to use a transient field won't work, as it just + * results in NPE. + */ + interface TestReference { + val testReference: NodeSchedulerServiceTest + } + + init { + val kms = MockKeyManagementService(ALICE_KEY) + val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(false, InMemoryMessagingNetwork.Handle(0, "None")) + val mockServices = object : MockServices(overrideClock = testClock, keyManagement = kms, net = mockMessagingService), TestReference { + override val testReference = this@NodeSchedulerServiceTest + } + services = mockServices + scheduler = NodeSchedulerService(mockServices, factory, schedulerGatedExecutor) + val mockSMM = StateMachineManager(mockServices, listOf(mockServices), PerFileCheckpointStorage(fs.getPath("checkpoints")), smmExecutor) + mockServices.smm = mockSMM + } + + lateinit var countDown: CountDownLatch + var calls: Int = 0 + + @Before + fun setup() { + countDown = CountDownLatch(1) + calls = 0 + } + + class TestState(val protocolLogicRef: ProtocolLogicRef, val instant: Instant) : LinearState, SchedulableState { + override val participants: List + get() = throw UnsupportedOperationException() + + override val thread = SecureHash.sha256("does not matter but we need it to be unique ${Math.random()}") + + override fun isRelevant(ourKeys: Set): Boolean = true + + override fun nextScheduledActivity(thisStateRef: StateRef, protocolLogicRefFactory: ProtocolLogicRefFactory): ScheduledActivity? = ScheduledActivity(protocolLogicRef, instant) + + override val contract: Contract + get() = throw UnsupportedOperationException() + } + + class TestProtocolLogic(val increment: Int = 1) : ProtocolLogic() { + override fun call() { + (serviceHub as TestReference).testReference.calls += increment + (serviceHub as TestReference).testReference.countDown.countDown() + } + override val topic: String get() = throw UnsupportedOperationException() + } + + class Command : TypeOnlyCommandData() + + @Test + fun `test activity due now`() { + val time = stoppedClock.instant() + scheduleTX(time) + + assertThat(calls).isEqualTo(0) + schedulerGatedExecutor.waitAndRun() + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(1) + } + + @Test + fun `test activity due in the past`() { + val time = stoppedClock.instant() - 1.days + scheduleTX(time) + + assertThat(calls).isEqualTo(0) + schedulerGatedExecutor.waitAndRun() + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(1) + } + + @Test + fun `test activity due in the future`() { + val time = stoppedClock.instant() + 1.days + scheduleTX(time) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + testClock.advanceBy(1.days) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(1) + } + + @Test + fun `test activity due in the future and schedule another earlier`() { + val time = stoppedClock.instant() + 1.days + scheduleTX(time + 1.days) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + scheduleTX(time, 3) + + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + testClock.advanceBy(1.days) + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(3) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + } + + @Test + fun `test activity due in the future and schedule another later`() { + val time = stoppedClock.instant() + 1.days + scheduleTX(time) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + scheduleTX(time + 1.days, 3) + + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + testClock.advanceBy(1.days) + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(1) + testClock.advanceBy(1.days) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + } + + @Test + fun `test activity due in the future and schedule another for same time`() { + val time = stoppedClock.instant() + 1.days + scheduleTX(time) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + scheduleTX(time, 3) + + testClock.advanceBy(1.days) + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(1) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + } + + @Test + fun `test activity due in the future and schedule another for same time then unschedule original`() { + val time = stoppedClock.instant() + 1.days + var scheduledRef1 = scheduleTX(time) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + scheduleTX(time, 3) + + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + scheduler.unscheduleStateActivity(scheduledRef1!!.ref) + testClock.advanceBy(1.days) + countDown.await(60, TimeUnit.SECONDS) + assertThat(calls).isEqualTo(3) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + } + + @Test + fun `test activity due in the future then unschedule`() { + var scheduledRef1 = scheduleTX(stoppedClock.instant() + 1.days) + + val backgroundExecutor = Executors.newSingleThreadExecutor() + backgroundExecutor.execute { schedulerGatedExecutor.waitAndRun() } + assertThat(calls).isEqualTo(0) + + scheduler.unscheduleStateActivity(scheduledRef1!!.ref) + testClock.advanceBy(1.days) + assertThat(calls).isEqualTo(0) + backgroundExecutor.shutdown() + backgroundExecutor.awaitTermination(60, TimeUnit.SECONDS) + } + + private fun scheduleTX(instant: Instant, increment: Int = 1): ScheduledStateRef? { + var scheduledRef: ScheduledStateRef? = null + apply { + val freshKey = services.keyManagementService.freshKey() + val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant) + val usefulTX = TransactionType.General.Builder(DUMMY_NOTARY).apply { + addOutputState(state) + addCommand(Command(), freshKey.public) + signWith(freshKey) + }.toSignedTransaction() + val txHash = usefulTX.id + + services.recordTransactions(usefulTX) + scheduledRef = ScheduledStateRef(StateRef(txHash, 0), state.instant) + scheduler.scheduleStateActivity(scheduledRef!!) + } + return scheduledRef + } +} \ No newline at end of file diff --git a/node/src/test/kotlin/node/services/NotaryChangeTests.kt b/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt similarity index 92% rename from node/src/test/kotlin/node/services/NotaryChangeTests.kt rename to node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt index 4059a1dcd9..a24501caa4 100644 --- a/node/src/test/kotlin/node/services/NotaryChangeTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/NotaryChangeTests.kt @@ -1,4 +1,4 @@ -package node.services +package com.r3corda.node.services import com.r3corda.core.crypto.Party import com.r3corda.core.crypto.generateKeyPair @@ -11,10 +11,10 @@ import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.SimpleNotaryService import org.junit.Before import org.junit.Test -import protocols.NotaryChangeException import protocols.NotaryChangeProtocol import protocols.NotaryChangeProtocol.Instigator -import protocols.NotaryChangeRefused +import protocols.StateReplacementException +import protocols.StateReplacementRefused import java.util.concurrent.ExecutionException import kotlin.test.assertEquals import kotlin.test.assertFailsWith @@ -46,7 +46,7 @@ class NotaryChangeTests { val state = issueState(clientNodeA) val newNotary = newNotaryNode.info.identity val protocol = Instigator(state, newNotary) - val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC_CHANGE, protocol) + val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC, protocol) net.runNetwork() @@ -59,7 +59,7 @@ class NotaryChangeTests { val state = issueMultiPartyState(clientNodeA, clientNodeB) val newNotary = newNotaryNode.info.identity val protocol = Instigator(state, newNotary) - val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC_CHANGE, protocol) + val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC, protocol) net.runNetwork() @@ -75,13 +75,13 @@ class NotaryChangeTests { val state = issueMultiPartyState(clientNodeA, clientNodeB) val newEvilNotary = Party("Evil Notary", generateKeyPair().public) val protocol = Instigator(state, newEvilNotary) - val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC_CHANGE, protocol) + val future = clientNodeA.smm.add(NotaryChangeProtocol.TOPIC, protocol) net.runNetwork() val ex = assertFailsWith(ExecutionException::class) { future.get() } - val error = (ex.cause as NotaryChangeException).error - assertTrue(error is NotaryChangeRefused) + val error = (ex.cause as StateReplacementException).error + assertTrue(error is StateReplacementRefused) } // TODO: Add more test cases once we have a general protocol/service exception handling mechanism: diff --git a/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt b/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt index 3cfe70e806..ce48cae626 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/WalletWithCashTest.kt @@ -1,7 +1,7 @@ package com.r3corda.node.services -import com.r3corda.contracts.cash.Cash -import com.r3corda.contracts.cash.cashBalances +import com.r3corda.contracts.asset.Cash +import com.r3corda.contracts.asset.cashBalances import com.r3corda.contracts.testing.fillWithSomeTestCash import com.r3corda.core.contracts.* import com.r3corda.core.crypto.SecureHash diff --git a/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt b/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt index 8877aeb059..5a7dd02003 100644 --- a/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt +++ b/node/src/test/kotlin/com/r3corda/node/services/statemachine/StateMachineManagerTests.kt @@ -59,6 +59,8 @@ class StateMachineManagerTests { protocolStarted = true Fiber.park() } + + override val topic: String get() = throw UnsupportedOperationException() } @@ -68,6 +70,8 @@ class StateMachineManagerTests { @Suspendable override fun call() {} + + override val topic: String get() = throw UnsupportedOperationException() } diff --git a/node/src/test/kotlin/com/r3corda/node/visualiser/GroupToGraphConversion.kt b/node/src/test/kotlin/com/r3corda/node/visualiser/GroupToGraphConversion.kt index 9cb29a4e18..6b61416d5a 100644 --- a/node/src/test/kotlin/com/r3corda/node/visualiser/GroupToGraphConversion.kt +++ b/node/src/test/kotlin/com/r3corda/node/visualiser/GroupToGraphConversion.kt @@ -2,35 +2,34 @@ package com.r3corda.node.visualiser import com.r3corda.core.contracts.CommandData import com.r3corda.core.contracts.ContractState -import com.r3corda.core.contracts.TransactionState import com.r3corda.core.crypto.SecureHash -import com.r3corda.core.testing.TransactionGroupDSL +import com.r3corda.core.testing.* import org.graphstream.graph.Edge import org.graphstream.graph.Node import org.graphstream.graph.implementations.SingleGraph import kotlin.reflect.memberProperties -class GraphVisualiser(val dsl: TransactionGroupDSL) { +class GraphVisualiser(val dsl: LedgerDSL) { companion object { val css = GraphVisualiser::class.java.getResourceAsStream("graph.css").bufferedReader().readText() } fun convert(): SingleGraph { - val tg = dsl.toTransactionGroup() + val tg = dsl.interpreter.toTransactionGroup() val graph = createGraph("Transaction group", css) // Map all the transactions, including the bogus non-verified ones (with no inputs) to graph nodes. for ((txIndex, tx) in (tg.transactions + tg.nonVerifiedRoots).withIndex()) { val txNode = graph.addNode("tx$txIndex") if (tx !in tg.nonVerifiedRoots) - txNode.label = dsl.labelForTransaction(tx).let { it ?: "TX ${tx.id.prefixChars()}" } + txNode.label = dsl.interpreter.transactionName(tx.id).let { it ?: "TX[${tx.id.prefixChars()}]" } txNode.styleClass = "tx" // Now create a vertex for each output state. for (outIndex in tx.outputs.indices) { val node = graph.addNode(tx.outRef(outIndex).ref.toString()) val state = tx.outputs[outIndex] - node.label = stateToLabel(state) + node.label = stateToLabel(state.data) node.styleClass = stateToCSSClass(state.data) + ",state" node.setAttribute("state", state) val edge = graph.addEdge("tx$txIndex-out$outIndex", txNode, node, true) @@ -56,8 +55,8 @@ class GraphVisualiser(val dsl: TransactionGroupDSL) { return graph } - private fun stateToLabel(state: TransactionState<*>): String { - return dsl.labelForState(state) ?: stateToTypeName(state.data) + private fun stateToLabel(state: ContractState): String { + return dsl.interpreter.outputToLabel(state) ?: stateToTypeName(state) } private fun commandToTypeName(state: CommandData) = state.javaClass.canonicalName.removePrefix("contracts.").replace('$', '.') @@ -73,4 +72,4 @@ class GraphVisualiser(val dsl: TransactionGroupDSL) { } }) } -} \ No newline at end of file +} diff --git a/src/integration-test/kotlin/com/r3corda/core/testing/IRSDemoTest.kt b/src/integration-test/kotlin/com/r3corda/core/testing/IRSDemoTest.kt new file mode 100644 index 0000000000..31cc7f9f22 --- /dev/null +++ b/src/integration-test/kotlin/com/r3corda/core/testing/IRSDemoTest.kt @@ -0,0 +1,94 @@ +package com.r3corda.core.testing + +import com.google.common.net.HostAndPort +import com.r3corda.core.testing.utilities.* +import kotlin.test.assertEquals +import org.junit.Test +import java.nio.file.Path +import java.nio.file.Paths + +class IRSDemoTest { + @Test fun `runs IRS demo`() { + val nodeAddrA = freeLocalHostAndPort() + val apiAddrA = freeLocalHostAndPort() + val apiAddrB = freeLocalHostAndPort() + + val baseDirectory = Paths.get("./build/integration-test/${TestTimestamp.timestamp}/irs-demo") + var procA: Process? = null + var procB: Process? = null + try { + setupNode(baseDirectory, "NodeA") + setupNode(baseDirectory, "NodeB") + procA = startNode( + baseDirectory = baseDirectory, + nodeType = "NodeA", + nodeAddr = nodeAddrA, + networkMapAddr = apiAddrA, + apiAddr = apiAddrA + ) + procB = startNode( + baseDirectory = baseDirectory, + nodeType = "NodeB", + nodeAddr = freeLocalHostAndPort(), + networkMapAddr = nodeAddrA, + apiAddr = apiAddrB + ) + runTrade(apiAddrA) + runDateChange(apiAddrA) + } finally { + stopNode(procA) + stopNode(procB) + } + } +} + +private fun setupNode(baseDirectory: Path, nodeType: String) { + println("Running setup for $nodeType") + val args = listOf("--role", "Setup" + nodeType, "--base-directory", baseDirectory.toString()) + val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemoSetup$nodeType") + assertExitOrKill(proc) + assertEquals(proc.exitValue(), 0) +} + +private fun startNode(baseDirectory: Path, + nodeType: String, + nodeAddr: HostAndPort, + networkMapAddr: HostAndPort, + apiAddr: HostAndPort): Process { + println("Running node $nodeType") + println("Node addr: $nodeAddr") + println("Network map addr: $networkMapAddr") + println("API addr: $apiAddr") + val args = listOf( + "--role", nodeType, + "--base-directory", baseDirectory.toString(), + "--network-address", nodeAddr.toString(), + "--network-map-address", networkMapAddr.toString(), + "--api-address", apiAddr.toString()) + val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemo$nodeType") + NodeApi.ensureNodeStartsOrKill(proc, apiAddr) + return proc +} + +private fun runTrade(nodeAddr: HostAndPort) { + println("Running trade") + val args = listOf("--role", "Trade", "trade1", "--api-address", nodeAddr.toString()) + val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemoTrade") + assertExitOrKill(proc) + assertEquals(proc.exitValue(), 0) +} + +private fun runDateChange(nodeAddr: HostAndPort) { + println("Running date change") + val args = listOf("--role", "Date", "2017-01-02", "--api-address", nodeAddr.toString()) + val proc = spawn("com.r3corda.demos.IRSDemoKt", args, "IRSDemoDate") + assertExitOrKill(proc) + assertEquals(proc.exitValue(), 0) +} + +private fun stopNode(nodeProc: Process?) { + if (nodeProc != null) { + println("Stopping node") + assertAliveAndKill(nodeProc) + } +} diff --git a/src/integration-test/kotlin/com/r3corda/core/testing/TraderDemoTest.kt b/src/integration-test/kotlin/com/r3corda/core/testing/TraderDemoTest.kt new file mode 100644 index 0000000000..57d8d49ad2 --- /dev/null +++ b/src/integration-test/kotlin/com/r3corda/core/testing/TraderDemoTest.kt @@ -0,0 +1,59 @@ +package com.r3corda.core.testing + +import com.google.common.net.HostAndPort +import com.r3corda.core.testing.utilities.NodeApi +import com.r3corda.core.testing.utilities.TestTimestamp +import com.r3corda.core.testing.utilities.assertExitOrKill +import com.r3corda.core.testing.utilities.spawn +import org.junit.Test +import java.nio.file.Paths +import java.text.SimpleDateFormat +import java.util.* +import kotlin.test.assertEquals + +class TraderDemoTest { + @Test fun `runs trader demo`() { + val buyerAddr = freeLocalHostAndPort() + val buyerApiAddr = freeLocalHostAndPort() + val directory = "./build/integration-test/${TestTimestamp.timestamp}/trader-demo" + var nodeProc: Process? = null + try { + nodeProc = runBuyer(directory, buyerAddr, buyerApiAddr) + runSeller(directory, buyerAddr) + } finally { + nodeProc?.destroy() + } + } + + companion object { + private fun runBuyer(baseDirectory: String, buyerAddr: HostAndPort, buyerApiAddr: HostAndPort): Process { + println("Running Buyer") + val args = listOf( + "--role", "BUYER", + "--network-address", buyerAddr.toString(), + "--api-address", buyerApiAddr.toString(), + "--base-directory", baseDirectory + ) + val proc = spawn("com.r3corda.demos.TraderDemoKt", args, "TradeDemoBuyer") + NodeApi.ensureNodeStartsOrKill(proc, buyerApiAddr) + return proc + } + + private fun runSeller(baseDirectory: String, buyerAddr: HostAndPort) { + println("Running Seller") + val sellerAddr = freeLocalHostAndPort() + val sellerApiAddr = freeLocalHostAndPort() + val args = listOf( + "--role", "SELLER", + "--network-address", sellerAddr.toString(), + "--api-address", sellerApiAddr.toString(), + "--other-network-address", buyerAddr.toString(), + "--base-directory", baseDirectory + ) + val proc = spawn("com.r3corda.demos.TraderDemoKt", args, "TradeDemoSeller") + assertExitOrKill(proc); + assertEquals(proc.exitValue(), 0) + } + + } +} diff --git a/src/integration-test/kotlin/com/r3corda/core/testing/utilities/JVMSpawner.kt b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/JVMSpawner.kt new file mode 100644 index 0000000000..2bd06445ca --- /dev/null +++ b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/JVMSpawner.kt @@ -0,0 +1,34 @@ +package com.r3corda.core.testing.utilities + +import java.nio.file.Paths +import java.util.concurrent.TimeUnit +import kotlin.test.assertEquals + +fun spawn(className: String, args: List, appName: String): Process { + val separator = System.getProperty("file.separator") + val classpath = System.getProperty("java.class.path") + val path = System.getProperty("java.home") + separator + "bin" + separator + "java" + val javaArgs = listOf(path, "-Dname=$appName", "-javaagent:lib/quasar.jar", "-cp", classpath, className) + val builder = ProcessBuilder(javaArgs + args) + builder.redirectError(Paths.get("error.$className.log").toFile()) + builder.inheritIO() + val process = builder.start(); + return process +} + +fun assertExitOrKill(proc: Process) { + try { + assertEquals(proc.waitFor(2, TimeUnit.MINUTES), true) + } catch (e: Throwable) { + proc.destroyForcibly() + throw e + } +} + +fun assertAliveAndKill(proc: Process) { + try { + assertEquals(proc.isAlive, true) + } finally { + proc.destroyForcibly() + } +} diff --git a/src/integration-test/kotlin/com/r3corda/core/testing/utilities/NodeApi.kt b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/NodeApi.kt new file mode 100644 index 0000000000..d29bb04035 --- /dev/null +++ b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/NodeApi.kt @@ -0,0 +1,61 @@ +package com.r3corda.core.testing.utilities + +import com.google.common.net.HostAndPort +import java.io.IOException +import java.io.InputStreamReader +import java.net.ConnectException +import java.net.SocketException +import java.net.HttpURLConnection +import java.net.URL +import kotlin.test.assertEquals + +class NodeApi { + class NodeDidNotStartException(message: String): Exception(message) + + companion object { + val NODE_WAIT_RETRY_COUNT: Int = 100 + val NODE_WAIT_RETRY_DELAY_MS: Long = 200 + + fun ensureNodeStartsOrKill(proc: Process, nodeWebserverAddr: HostAndPort) { + try { + assertEquals(proc.isAlive, true) + waitForNodeStartup(nodeWebserverAddr) + } catch (e: Throwable) { + println("Forcibly killing node process") + proc.destroyForcibly() + throw e + } + } + + private fun waitForNodeStartup(nodeWebserverAddr: HostAndPort) { + val url = URL("http://${nodeWebserverAddr.toString()}/api/status") + var retries = 0 + var respCode: Int + do { + retries++ + val err = try { + val conn = url.openConnection() as HttpURLConnection + conn.requestMethod = "GET" + respCode = conn.responseCode + InputStreamReader(conn.inputStream).readLines().joinToString { it } + } catch(e: ConnectException) { + // This is to be expected while it loads up + respCode = 404 + "Node hasn't started" + } catch(e: SocketException) { + respCode = -1 + "Could not connect: ${e.toString()}" + } catch (e: IOException) { + respCode = -1 + "IOException: ${e.toString()}" + } + + if (retries > NODE_WAIT_RETRY_COUNT) { + throw NodeDidNotStartException("The node did not start: " + err) + } + + Thread.sleep(NODE_WAIT_RETRY_DELAY_MS) + } while (respCode != 200) + } + } +} diff --git a/src/integration-test/kotlin/com/r3corda/core/testing/utilities/TestTimestamp.kt b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/TestTimestamp.kt new file mode 100644 index 0000000000..b620d54524 --- /dev/null +++ b/src/integration-test/kotlin/com/r3corda/core/testing/utilities/TestTimestamp.kt @@ -0,0 +1,19 @@ +package com.r3corda.core.testing.utilities + +import java.text.SimpleDateFormat +import java.util.* + +/** + * [timestamp] holds a formatted (UTC) timestamp that's set the first time it is queried. This is used to + * provide a uniform timestamp for tests + */ +class TestTimestamp { + companion object { + val timestamp: String = { + val tz = TimeZone.getTimeZone("UTC") + val df = SimpleDateFormat("yyyyMMddHHmmss") + df.timeZone = tz + df.format(Date()) + }() + } +} diff --git a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt index e1d270b6bb..619287e7de 100644 --- a/src/main/kotlin/com/r3corda/demos/IRSDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/IRSDemo.kt @@ -1,18 +1,13 @@ package com.r3corda.demos import com.google.common.net.HostAndPort -import com.typesafe.config.ConfigFactory +import com.r3corda.contracts.InterestRateSwap import com.r3corda.core.crypto.Party import com.r3corda.core.logElapsedTime -import com.r3corda.node.internal.Node -import com.r3corda.node.services.config.NodeConfiguration -import com.r3corda.node.services.config.NodeConfigurationFromConfig +import com.r3corda.core.messaging.SingleMessageRecipient +import com.r3corda.core.node.CordaPluginRegistry import com.r3corda.core.node.NodeInfo -import com.r3corda.node.services.network.NetworkMapService -import com.r3corda.node.services.clientapi.NodeInterestRates -import com.r3corda.node.services.transactions.NotaryService import com.r3corda.core.node.services.ServiceType -import com.r3corda.node.services.messaging.ArtemisMessagingService import com.r3corda.core.serialization.deserialize import com.r3corda.core.utilities.BriefLogFormatter import com.r3corda.demos.api.InterestRateSwapAPI @@ -20,15 +15,20 @@ import com.r3corda.demos.protocols.AutoOfferProtocol import com.r3corda.demos.protocols.ExitServerProtocol import com.r3corda.demos.protocols.UpdateBusinessDayProtocol import com.r3corda.node.internal.AbstractNode +import com.r3corda.node.internal.Node import com.r3corda.node.internal.testing.MockNetwork -import com.r3corda.node.services.network.InMemoryMessagingNetwork +import com.r3corda.node.services.FixingSessionInitiationHandler +import com.r3corda.node.services.clientapi.NodeInterestRates +import com.r3corda.node.services.config.NodeConfiguration +import com.r3corda.node.services.config.NodeConfigurationFromConfig +import com.r3corda.node.services.messaging.ArtemisMessagingService +import com.r3corda.node.services.network.NetworkMapService import com.r3corda.node.services.transactions.SimpleNotaryService +import com.typesafe.config.ConfigFactory import joptsimple.OptionParser import joptsimple.OptionSet -import joptsimple.OptionSpec -import java.io.DataOutputStream +import org.apache.commons.io.IOUtils import java.io.File -import java.net.HttpURLConnection import java.net.URL import java.nio.file.Files import java.nio.file.Path @@ -36,17 +36,19 @@ import java.nio.file.Paths import java.util.* import kotlin.concurrent.fixedRateTimer import kotlin.system.exitProcess -import org.apache.commons.io.IOUtils -import java.io.FileNotFoundException +import com.r3corda.demos.utilities.* // IRS DEMO // // Please see docs/build/html/running-the-trading-demo.html -// -// TODO: TBD -// -// The different roles in the scenario this program can adopt are: +/** + * Roles. There are 4 modes this demo can be run: + * - SetupNodeA/SetupNodeB: Creates and sets up the necessary directories for nodes + * - NodeA/NodeB: Starts the nodes themselves + * - Trade: Uploads an example trade + * - DateChange: Changes the demo's date + */ enum class IRSDemoRole { SetupNodeA, SetupNodeB, @@ -56,27 +58,195 @@ enum class IRSDemoRole { Date } -private class NodeParams() { - var id: Int = -1 - var dir : Path = Paths.get("") - var address : String = "" - var mapAddress: String = "" - var identityFile: Path = Paths.get("") - var tradeWithAddrs: List = listOf() - var tradeWithIdentities: List = listOf() - var uploadRates: Boolean = false - var defaultLegalName: String = "" +/** + * Parsed command line parameters. + */ +sealed class CliParams { + + /** + * Corresponds to roles 'SetupNodeA' and 'SetupNodeB' + */ + class SetupNode( + val node: IRSDemoNode, + val dir: Path, + val defaultLegalName: String + ) : CliParams() + + /** + * Corresponds to roles 'NodeA' and 'NodeB' + */ + class RunNode( + val node: IRSDemoNode, + val dir: Path, + val networkAddress : HostAndPort, + val apiAddress: HostAndPort, + val mapAddress: String, + val identityFile: Path, + val tradeWithAddrs: List, + val tradeWithIdentities: List, + val uploadRates: Boolean, + val defaultLegalName: String, + val autoSetup: Boolean // Run Setup for both nodes automatically with default arguments + ) : CliParams() + + /** + * Corresponds to role 'Trade' + */ + class Trade( + val apiAddress: HostAndPort, + val tradeId: String + ) : CliParams() + + /** + * Corresponds to role 'Date' + */ + class DateChange( + val apiAddress: HostAndPort, + val dateString: String + ) : CliParams() + + companion object { + + val defaultBaseDirectory = "./build/irs-demo" + + fun legalName(node: IRSDemoNode) = + when (node) { + IRSDemoNode.NodeA -> "Bank A" + IRSDemoNode.NodeB -> "Bank B" + } + + private fun nodeDirectory(options: OptionSet, node: IRSDemoNode) = + Paths.get(options.valueOf(CliParamsSpec.baseDirectoryArg), node.name.decapitalize()) + + private fun parseSetupNode(options: OptionSet, node: IRSDemoNode): SetupNode { + return SetupNode( + node = node, + dir = nodeDirectory(options, node), + defaultLegalName = legalName(node) + ) + } + + private fun defaultNetworkPort(node: IRSDemoNode) = + when (node) { + IRSDemoNode.NodeA -> Node.DEFAULT_PORT + IRSDemoNode.NodeB -> Node.DEFAULT_PORT + 2 + } + + private fun defaultApiPort(node: IRSDemoNode) = + when (node) { + IRSDemoNode.NodeA -> Node.DEFAULT_PORT + 1 + IRSDemoNode.NodeB -> Node.DEFAULT_PORT + 3 + } + + private fun parseRunNode(options: OptionSet, node: IRSDemoNode): RunNode { + val dir = nodeDirectory(options, node) + + return RunNode( + node = node, + dir = dir, + networkAddress = HostAndPort.fromString(options.valueOf( + CliParamsSpec.networkAddressArg.defaultsTo("localhost:${defaultNetworkPort(node)}") + )), + apiAddress = HostAndPort.fromString(options.valueOf( + CliParamsSpec.apiAddressArg.defaultsTo("localhost:${defaultApiPort(node)}") + )), + mapAddress = options.valueOf(CliParamsSpec.networkMapNetAddr), + identityFile = if (options.has(CliParamsSpec.networkMapIdentityFile)) { + Paths.get(options.valueOf(CliParamsSpec.networkMapIdentityFile)) + } else { + dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME) + }, + tradeWithAddrs = if (options.has(CliParamsSpec.fakeTradeWithAddr)) { + options.valuesOf(CliParamsSpec.fakeTradeWithAddr) + } else { + listOf("localhost:${defaultNetworkPort(node.other)}") + }, + tradeWithIdentities = if (options.has(CliParamsSpec.fakeTradeWithIdentityFile)) { + options.valuesOf(CliParamsSpec.fakeTradeWithIdentityFile).map { Paths.get(it) } + } else { + listOf(nodeDirectory(options, node.other).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME)) + }, + uploadRates = node == IRSDemoNode.NodeB, + defaultLegalName = legalName(node), + autoSetup = !options.has(CliParamsSpec.baseDirectoryArg) && !options.has(CliParamsSpec.fakeTradeWithIdentityFile) + ) + } + + private fun parseTrade(options: OptionSet): Trade { + return Trade( + apiAddress = HostAndPort.fromString(options.valueOf( + CliParamsSpec.apiAddressArg.defaultsTo("localhost:${defaultApiPort(IRSDemoNode.NodeA)}") + )), + tradeId = options.valuesOf(CliParamsSpec.nonOptions).let { + if (it.size > 0) { + it[0] + } else { + throw IllegalArgumentException("Please provide a trade ID") + } + } + ) + } + + private fun parseDateChange(options: OptionSet): DateChange { + return DateChange( + apiAddress = HostAndPort.fromString(options.valueOf( + CliParamsSpec.apiAddressArg.defaultsTo("localhost:${defaultApiPort(IRSDemoNode.NodeA)}") + )), + dateString = options.valuesOf(CliParamsSpec.nonOptions).let { + if (it.size > 0) { + it[0] + } else { + throw IllegalArgumentException("Please provide a date string") + } + } + ) + } + + fun parse(options: OptionSet): CliParams { + val role = options.valueOf(CliParamsSpec.roleArg)!! + return when (role) { + IRSDemoRole.SetupNodeA -> parseSetupNode(options, IRSDemoNode.NodeA) + IRSDemoRole.SetupNodeB -> parseSetupNode(options, IRSDemoNode.NodeB) + IRSDemoRole.NodeA -> parseRunNode(options, IRSDemoNode.NodeA) + IRSDemoRole.NodeB -> parseRunNode(options, IRSDemoNode.NodeB) + IRSDemoRole.Trade -> parseTrade(options) + IRSDemoRole.Date -> parseDateChange(options) + } + } + } } -private class DemoArgs() { - lateinit var roleArg: OptionSpec - lateinit var networkAddressArg: OptionSpec - lateinit var dirArg: OptionSpec - lateinit var networkMapIdentityFile: OptionSpec - lateinit var networkMapNetAddr: OptionSpec - lateinit var fakeTradeWithAddr: OptionSpec - lateinit var fakeTradeWithIdentityFile: OptionSpec - lateinit var nonOptions: OptionSpec +enum class IRSDemoNode { + NodeA, + NodeB; + + val other: IRSDemoNode get() { + return when (this) { + NodeA -> NodeB + NodeB -> NodeA + } + } +} + +object CliParamsSpec { + val parser = OptionParser() + val roleArg = parser.accepts("role").withRequiredArg().ofType(IRSDemoRole::class.java) + val networkAddressArg = parser.accepts("network-address").withOptionalArg().ofType(String::class.java) + val apiAddressArg = parser.accepts("api-address").withOptionalArg().ofType(String::class.java) + val baseDirectoryArg = parser.accepts("base-directory").withOptionalArg().defaultsTo(CliParams.defaultBaseDirectory) + val networkMapIdentityFile = parser.accepts("network-map-identity-file").withOptionalArg() + val networkMapNetAddr = parser.accepts("network-map-address").withRequiredArg().defaultsTo("localhost") + val fakeTradeWithAddr = parser.accepts("fake-trade-with-address").withOptionalArg() + val fakeTradeWithIdentityFile = parser.accepts("fake-trade-with-identity-file").withOptionalArg() + val nonOptions = parser.nonOptions() +} + +class IRSDemoPluginRegistry : CordaPluginRegistry { + override val webApis: List> = listOf(InterestRateSwapAPI::class.java) + override val requiredProtocols: Map> = mapOf( + Pair(AutoOfferProtocol.Requester::class.java.name, setOf(InterestRateSwap.State::class.java.name)), + Pair(UpdateBusinessDayProtocol.Broadcast::class.java.name, setOf(java.time.LocalDate::class.java.name)), + Pair(ExitServerProtocol.Broadcast::class.java.name, setOf(kotlin.Int::class.java.name))) } private class NotSetupException: Throwable { @@ -84,180 +254,169 @@ private class NotSetupException: Throwable { } fun main(args: Array) { - val parser = OptionParser() - val demoArgs = setupArgs(parser) - val options = try { - parser.parse(*args) + exitProcess(runIRSDemo(args)) +} + +fun runIRSDemo(args: Array): Int { + val cliParams = try { + CliParams.parse(CliParamsSpec.parser.parse(*args)) } catch (e: Exception) { - println(e.message) - printHelp() - exitProcess(1) + println(e) + printHelp(CliParamsSpec.parser) + return 1 } // Suppress the Artemis MQ noise, and activate the demo logging. BriefLogFormatter.initVerbose("+demo.irsdemo", "+api-call", "+platform.deal", "-org.apache.activemq") - val role = options.valueOf(demoArgs.roleArg)!! - if(role == IRSDemoRole.SetupNodeA) { - val nodeParams = configureNodeParams(IRSDemoRole.NodeA, demoArgs, options) - setup(nodeParams) - } else if(role == IRSDemoRole.SetupNodeB) { - val nodeParams = configureNodeParams(IRSDemoRole.NodeB, demoArgs, options) - setup(nodeParams) - } else if(role == IRSDemoRole.Trade) { - val tradeIdArgs = options.valuesOf(demoArgs.nonOptions) - if (tradeIdArgs.size > 0) { - val tradeId = tradeIdArgs[0] - val host = if (options.has(demoArgs.networkAddressArg)) { - options.valueOf(demoArgs.networkAddressArg) - } else { - "http://localhost:" + (Node.DEFAULT_PORT + 1) - } - - if (runTrade(tradeId, host)) { - exitProcess(0) - } else { - exitProcess(1) - } - } else { - println("Please provide a trade ID") - exitProcess(1) - } - } else if(role == IRSDemoRole.Date) { - val dateStrArgs = options.valuesOf(demoArgs.nonOptions) - if (dateStrArgs.size > 0) { - val dateStr = dateStrArgs[0] - val host = if (options.has(demoArgs.networkAddressArg)) { - options.valueOf(demoArgs.networkAddressArg) - } else { - "http://localhost:" + (Node.DEFAULT_PORT + 1) - } - - runDateChange(dateStr, host) - } else { - println("Please provide a date") - exitProcess(1) - } - } else { - // If these directory and identity file arguments aren't specified then we can assume a default setup and - // create everything that is needed without needing to run setup. - if(!options.has(demoArgs.dirArg) && !options.has(demoArgs.fakeTradeWithIdentityFile)) { - createNodeConfig(createNodeAParams()); - createNodeConfig(createNodeBParams()); - } - - try { - runNode(configureNodeParams(role, demoArgs, options)) - } catch (e: NotSetupException) { - println(e.message) - exitProcess(1) - } - - exitProcess(0) + return when (cliParams) { + is CliParams.SetupNode -> setup(cliParams) + is CliParams.RunNode -> runNode(cliParams) + is CliParams.Trade -> runTrade(cliParams) + is CliParams.DateChange -> runDateChange(cliParams) } } -private fun setupArgs(parser: OptionParser): DemoArgs { - val args = DemoArgs() +private fun setup(params: CliParams.SetupNode): Int { + val dirFile = params.dir.toFile() + if (!dirFile.exists()) { + dirFile.mkdirs() + } - args.roleArg = parser.accepts("role").withRequiredArg().ofType(IRSDemoRole::class.java).required() - args.networkAddressArg = parser.accepts("network-address").withOptionalArg() - args.dirArg = parser.accepts("directory").withOptionalArg() - args.networkMapIdentityFile = parser.accepts("network-map-identity-file").withOptionalArg() - args.networkMapNetAddr = parser.accepts("network-map-address").withRequiredArg().defaultsTo("localhost") - // Use these to list one or more peers (again, will be superseded by discovery implementation) - args.fakeTradeWithAddr = parser.accepts("fake-trade-with-address").withOptionalArg() - args.fakeTradeWithIdentityFile = parser.accepts("fake-trade-with-identity-file").withOptionalArg() - args.nonOptions = parser.nonOptions().ofType(String::class.java) - - return args + val configFile = params.dir.resolve("config").toFile() + val config = loadConfigFile(configFile, params.defaultLegalName) + if (!Files.exists(params.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))) { + createIdentities(params, config) + } + return 0 } -private fun setup(params: NodeParams) { - createNodeConfig(params) -} +private fun defaultNodeSetupParams(node: IRSDemoNode): CliParams.SetupNode = + CliParams.SetupNode( + node = node, + dir = Paths.get(CliParams.defaultBaseDirectory, node.name.decapitalize()), + defaultLegalName = CliParams.legalName(node) + ) -private fun runDateChange(date: String, host: String) : Boolean { - val url = URL(host + "/api/irs/demodate") - if(putJson(url, "\"" + date + "\"")) { - println("Date changed") - return true - } else { - println("Date failed to change") - return false - } -} - -private fun runTrade(tradeId: String, host: String) : Boolean { - println("Uploading tradeID " + tradeId) - val fileContents = IOUtils.toString(NodeParams::class.java.getResourceAsStream("example-irs-trade.json")) - val tradeFile = fileContents.replace("tradeXXX", tradeId) - val url = URL(host + "/api/irs/deals") - if(postJson(url, tradeFile)) { - println("Trade sent") - return true - } else { - println("Trade failed to send") - return false - } -} - -private fun configureNodeParams(role: IRSDemoRole, args: DemoArgs, options: OptionSet): NodeParams { - val nodeParams = when (role) { - IRSDemoRole.NodeA -> createNodeAParams() - IRSDemoRole.NodeB -> createNodeBParams() - else -> { - throw IllegalArgumentException() - } - } - - nodeParams.mapAddress = options.valueOf(args.networkMapNetAddr) - if (options.has(args.dirArg)) { - nodeParams.dir = Paths.get(options.valueOf(args.dirArg)) - } - if (options.has(args.networkAddressArg)) { - nodeParams.address = options.valueOf(args.networkAddressArg) - } - nodeParams.identityFile = if (options.has(args.networkMapIdentityFile)) { - Paths.get(options.valueOf(args.networkMapIdentityFile)) - } else { - nodeParams.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME) - } - if (options.has(args.fakeTradeWithIdentityFile)) { - nodeParams.tradeWithIdentities = options.valuesOf(args.fakeTradeWithIdentityFile).map { Paths.get(it) } - } - if (options.has(args.fakeTradeWithAddr)) { - nodeParams.tradeWithAddrs = options.valuesOf(args.fakeTradeWithAddr) - } - - return nodeParams -} - -private fun runNode(nodeParams : NodeParams) : Unit { - val node = startNode(nodeParams) - // Register handlers for the demo - AutoOfferProtocol.Handler.register(node) - UpdateBusinessDayProtocol.Handler.register(node) - ExitServerProtocol.Handler.register(node) - - if(nodeParams.uploadRates) { - runUploadRates() +private fun runNode(cliParams: CliParams.RunNode): Int { + if (cliParams.autoSetup) { + setup(defaultNodeSetupParams(IRSDemoNode.NodeA)) + setup(defaultNodeSetupParams(IRSDemoNode.NodeB)) } try { - while (true) Thread.sleep(Long.MAX_VALUE) - } catch(e: InterruptedException) { - node.stop() + val networkMap = createRecipient(cliParams.mapAddress) + val destinations = cliParams.tradeWithAddrs.map({ + createRecipient(it) + }) + + val node = startNode(cliParams, networkMap, destinations) + // Register handlers for the demo + AutoOfferProtocol.Handler.register(node) + UpdateBusinessDayProtocol.Handler.register(node) + ExitServerProtocol.Handler.register(node) + FixingSessionInitiationHandler.register(node) + + if (cliParams.uploadRates) { + runUploadRates(cliParams.apiAddress) + } + + try { + while (true) Thread.sleep(Long.MAX_VALUE) + } catch(e: InterruptedException) { + node.stop() + } + } catch (e: NotSetupException) { + println(e.message) + return 1 + } + + return 0 +} + +private fun runDateChange(cliParams: CliParams.DateChange): Int { + println("Changing date to " + cliParams.dateString) + val url = URL("http://${cliParams.apiAddress}/api/irs/demodate") + if (putJson(url, "\"" + cliParams.dateString + "\"")) { + println("Date changed") + return 0 + } else { + println("Date failed to change") + return 1 } } -private fun runUploadRates() { - val fileContents = IOUtils.toString(NodeParams::class.java.getResource("example.rates.txt")) +private fun runTrade(cliParams: CliParams.Trade): Int { + println("Uploading tradeID " + cliParams.tradeId) + // Note: the getResourceAsStream is an ugly hack to get the jvm to search in the right location + val fileContents = IOUtils.toString(CliParams::class.java.getResourceAsStream("example-irs-trade.json")) + val tradeFile = fileContents.replace("tradeXXX", cliParams.tradeId) + val url = URL("http://${cliParams.apiAddress}/api/irs/deals") + if (postJson(url, tradeFile)) { + println("Trade sent") + return 0 + } else { + println("Trade failed to send") + return 1 + } +} + +private fun createRecipient(addr: String) : SingleMessageRecipient { + val hostAndPort = HostAndPort.fromString(addr).withDefaultPort(Node.DEFAULT_PORT) + return ArtemisMessagingService.makeRecipient(hostAndPort) +} + +private fun startNode(params: CliParams.RunNode, networkMap: SingleMessageRecipient, recipients: List) : Node { + val config = getNodeConfig(params) + val advertisedServices: Set + val networkMapId = + when (params.node) { + IRSDemoNode.NodeA -> { + advertisedServices = setOf(NetworkMapService.Type, SimpleNotaryService.Type) + null + } + IRSDemoNode.NodeB -> { + advertisedServices = setOf(NodeInterestRates.Type) + nodeInfo(networkMap, params.identityFile, setOf(NetworkMapService.Type, SimpleNotaryService.Type)) + } + } + + val node = logElapsedTime("Node startup") { + Node(params.dir, params.networkAddress, params.apiAddress, config, networkMapId, advertisedServices, DemoClock()).start() + } + + // TODO: This should all be replaced by the identity service being updated + // as the network map changes. + if (params.tradeWithAddrs.size != params.tradeWithIdentities.size) { + throw IllegalArgumentException("Different number of peer addresses (${params.tradeWithAddrs.size}) and identities (${params.tradeWithIdentities.size})") + } + for ((recipient, identityFile) in recipients.zip(params.tradeWithIdentities)) { + val peerId = nodeInfo(recipient, identityFile) + node.services.identityService.registerIdentity(peerId.identity) + } + + return node +} + +private fun nodeInfo(recipient: SingleMessageRecipient, identityFile: Path, advertisedServices: Set = emptySet()): NodeInfo { + try { + val path = identityFile + val party = Files.readAllBytes(path).deserialize() + return NodeInfo(recipient, party, advertisedServices) + } catch (e: Exception) { + println("Could not find identify file $identityFile.") + throw e + } +} + +private fun runUploadRates(host: HostAndPort) { + // Note: the getResourceAsStream is an ugly hack to get the jvm to search in the right location + val fileContents = IOUtils.toString(CliParams::class.java.getResourceAsStream("example.rates.txt")) var timer : Timer? = null timer = fixedRateTimer("upload-rates", false, 0, 5000, { try { - val url = URL("http://localhost:31341/upload/interest-rates") - if(uploadFile(url, fileContents)) { + val url = URL("http://${host.toString()}/upload/interest-rates") + if (uploadFile(url, fileContents)) { timer!!.cancel() println("Rates uploaded successfully") } else { @@ -269,184 +428,17 @@ private fun runUploadRates() { }) } -// Todo: Use a simpler library function for this and handle timeout exceptions -private fun sendJson(url: URL, data: String, method: String) : Boolean { - val connection = url.openConnection() as HttpURLConnection - connection.doOutput = true - connection.useCaches = false - connection.requestMethod = method - connection.connectTimeout = 5000 - connection.readTimeout = 5000 - connection.setRequestProperty("Connection", "Keep-Alive") - connection.setRequestProperty("Cache-Control", "no-cache") - connection.setRequestProperty("Content-Type", "application/json") - connection.setRequestProperty("Content-Length", data.length.toString()) - val outStream = DataOutputStream(connection.outputStream) - outStream.writeBytes(data) - outStream.close() - - return when(connection.responseCode) { - 200 -> true - 201 -> true - else -> { - println("Failed to " + method + " data. Status Code: " + connection.responseCode + ". Mesage: " + connection.responseMessage) - false - } - } -} - -private fun putJson(url: URL, data: String) : Boolean { - return sendJson(url, data, "PUT") -} - -private fun postJson(url: URL, data: String) : Boolean { - return sendJson(url, data, "POST") -} - -// Todo: Use a simpler library function for this and handle timeout exceptions -private fun uploadFile(url: URL, file: String) : Boolean { - val boundary = "===" + System.currentTimeMillis() + "===" - val hyphens = "--" - val clrf = "\r\n" - - val connection = url.openConnection() as HttpURLConnection - connection.doOutput = true - connection.doInput = true - connection.useCaches = false - connection.requestMethod = "POST" - connection.connectTimeout = 5000 - connection.readTimeout = 5000 - connection.setRequestProperty("Connection", "Keep-Alive") - connection.setRequestProperty("Cache-Control", "no-cache") - connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary) - - val request = DataOutputStream(connection.outputStream) - request.writeBytes(hyphens + boundary + clrf) - request.writeBytes("Content-Disposition: form-data; name=\"rates\" filename=\"example.rates.txt\"" + clrf) - request.writeBytes(clrf) - request.writeBytes(file) - request.writeBytes(clrf) - request.writeBytes(hyphens + boundary + hyphens + clrf) - - if (connection.responseCode == 200) { - return true - } else { - println("Could not upload file. Status Code: " + connection + ". Mesage: " + connection.responseMessage) - return false - } -} - -private fun createNodeAParams() : NodeParams { - val params = NodeParams() - params.id = 0 - params.dir = Paths.get("nodeA") - params.address = "localhost" - params.tradeWithAddrs = listOf("localhost:31340") - params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeB).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME)) - params.defaultLegalName = "Bank A" - return params -} - -private fun createNodeBParams() : NodeParams { - val params = NodeParams() - params.id = 1 - params.dir = Paths.get("nodeB") - params.address = "localhost:31340" - params.tradeWithAddrs = listOf("localhost") - params.tradeWithIdentities = listOf(getRoleDir(IRSDemoRole.NodeA).resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME)) - params.defaultLegalName = "Bank B" - params.uploadRates = true - return params -} - -private fun createNodeConfig(params: NodeParams) : NodeConfiguration { - if (!Files.exists(params.dir)) { - Files.createDirectory(params.dir) - } - - val configFile = params.dir.resolve("config").toFile() - val config = loadConfigFile(configFile, params.defaultLegalName) - if(!Files.exists(params.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))) { - createIdentities(params, config) - } - - return config -} - -private fun getNodeConfig(params: NodeParams): NodeConfiguration { - if(!Files.exists(params.dir)) { +private fun getNodeConfig(cliParams: CliParams.RunNode): NodeConfiguration { + if (!Files.exists(cliParams.dir)) { throw NotSetupException("Missing config directory. Please run node setup before running the node") } - if(!Files.exists(params.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))) { + if (!Files.exists(cliParams.dir.resolve(AbstractNode.PUBLIC_IDENTITY_FILE_NAME))) { throw NotSetupException("Missing identity file. Please run node setup before running the node") } - val configFile = params.dir.resolve("config").toFile() - return loadConfigFile(configFile, params.defaultLegalName) -} - -private fun startNode(params : NodeParams) : Node { - val config = getNodeConfig(params) - val advertisedServices: Set - val myNetAddr = HostAndPort.fromString(params.address).withDefaultPort(Node.DEFAULT_PORT) - val networkMapId = if (params.mapAddress.equals(params.address)) { - // This node provides network map and notary services - advertisedServices = setOf(NetworkMapService.Type, SimpleNotaryService.Type) - null - } else { - advertisedServices = setOf(NodeInterestRates.Type) - nodeInfo(params.mapAddress, params.identityFile, setOf(NetworkMapService.Type, SimpleNotaryService.Type)) - } - - val node = logElapsedTime("Node startup") { Node(params.dir, myNetAddr, config, networkMapId, - advertisedServices, DemoClock(), - listOf(InterestRateSwapAPI::class.java)).setup().start() } - - // TODO: This should all be replaced by the identity service being updated - // as the network map changes. - if (params.tradeWithAddrs.size != params.tradeWithIdentities.size) { - throw IllegalArgumentException("Different number of peer addresses (${params.tradeWithAddrs.size}) and identities (${params.tradeWithIdentities.size})") - } - for ((hostAndPortString, identityFile) in params.tradeWithAddrs.zip(params.tradeWithIdentities)) { - val peerId = nodeInfo(hostAndPortString, identityFile) - node.services.identityService.registerIdentity(peerId.identity) - } - - return node -} - -private fun getRoleDir(role: IRSDemoRole) : Path { - when(role) { - IRSDemoRole.NodeA -> return Paths.get("nodeA") - IRSDemoRole.NodeB -> return Paths.get("nodeB") - else -> { - throw IllegalArgumentException() - } - } -} - -private fun nodeInfo(hostAndPortString: String, identityFile: Path, advertisedServices: Set = emptySet()): NodeInfo { - try { - val addr = HostAndPort.fromString(hostAndPortString).withDefaultPort(Node.DEFAULT_PORT) - val path = identityFile - val party = Files.readAllBytes(path).deserialize() - return NodeInfo(ArtemisMessagingService.makeRecipient(addr), party, advertisedServices) - } catch (e: Exception) { - println("Could not find identify file $identityFile.") - throw e - } -} - -private fun nodeInfo(handle: InMemoryMessagingNetwork.Handle, identityFile: Path, advertisedServices: Set = emptySet()): NodeInfo { - try { - val path = identityFile - val party = Files.readAllBytes(path).deserialize() - return NodeInfo(handle, party, advertisedServices) - } catch (e: Exception) { - println("Could not find identify file $identityFile.") - throw e - } + val configFile = cliParams.dir.resolve("config").toFile() + return loadConfigFile(configFile, cliParams.defaultLegalName) } private fun loadConfigFile(configFile: File, defaultLegalName: String): NodeConfiguration { @@ -459,9 +451,9 @@ private fun loadConfigFile(configFile: File, defaultLegalName: String): NodeConf return NodeConfigurationFromConfig(config) } -private fun createIdentities(params: NodeParams, nodeConf: NodeConfiguration) { +private fun createIdentities(params: CliParams.SetupNode, nodeConf: NodeConfiguration) { val mockNetwork = MockNetwork(false) - val node = MockNetwork.MockNode(params.dir, nodeConf, mockNetwork, null, setOf(NetworkMapService.Type, SimpleNotaryService.Type), params.id, null) + val node = MockNetwork.MockNode(params.dir, nodeConf, mockNetwork, null, setOf(NetworkMapService.Type, SimpleNotaryService.Type), 0, null) node.start() node.stop() } @@ -473,8 +465,11 @@ private fun createDefaultConfigFile(configFile: File, legalName: String) { """.trimIndent().toByteArray()) } -private fun printHelp() { +private fun printHelp(parser: OptionParser) { println(""" - Please refer to the documentation in docs/build/index.html to learn how to run the demo. + Usage: irsdemo --role [NodeA|NodeB|Trade|Date] [|] [options] + Please refer to the documentation in docs/build/index.html for more info. + """.trimIndent()) + parser.printHelpOn(System.out) } diff --git a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt index ee5f7fa4de..1374c58dd4 100644 --- a/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/RateFixDemo.kt @@ -1,8 +1,10 @@ package com.r3corda.demos -import com.r3corda.contracts.cash.Cash +import com.google.common.net.HostAndPort +import com.r3corda.contracts.asset.Cash import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party +import com.r3corda.core.hours import com.r3corda.core.logElapsedTime import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.services.ServiceType @@ -63,7 +65,7 @@ fun main(args: Array) { val rateTolerance = BigDecimal(options.valueOf(rateToleranceArg)) // Bring up node. - var advertisedServices: Set = emptySet() + val advertisedServices: Set = emptySet() val myNetAddr = ArtemisMessagingService.toHostAndPort(options.valueOf(networkAddressArg)) val config = object : NodeConfiguration { override val myLegalName: String = "Rate fix demo node" @@ -71,16 +73,17 @@ fun main(args: Array) { override val nearestCity: String = "Atlantis" } - val node = logElapsedTime("Node startup") { Node(dir, myNetAddr, config, networkMapAddress, - advertisedServices, DemoClock(), - listOf(InterestRateSwapAPI::class.java)).setup().start() } + val apiAddr = HostAndPort.fromParts(myNetAddr.hostText, myNetAddr.port + 1) + + val node = logElapsedTime("Node startup") { Node(dir, myNetAddr, apiAddr, config, networkMapAddress, + advertisedServices, DemoClock()).setup().start() } val notary = node.services.networkMapCache.notaryNodes[0] // Make a garbage transaction that includes a rate fix. val tx = TransactionType.General.Builder() tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.storage.myLegalIdentity.ref(1), node.keyManagement.freshKey().public), notary.identity)) - val protocol = RatesFixProtocol(tx, oracleNode, fixOf, expectedRate, rateTolerance) + val protocol = RatesFixProtocol(tx, oracleNode.identity, fixOf, expectedRate, rateTolerance, 24.hours) node.smm.add("demo.ratefix", protocol).get() node.stop() @@ -89,4 +92,4 @@ fun main(args: Array) { println() print(Emoji.renderIfSupported(tx.toWireTransaction())) println(tx.toSignedTransaction().sigs) -} \ No newline at end of file +} diff --git a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt index 90d7917d7d..d994281a20 100644 --- a/src/main/kotlin/com/r3corda/demos/TraderDemo.kt +++ b/src/main/kotlin/com/r3corda/demos/TraderDemo.kt @@ -3,7 +3,7 @@ package com.r3corda.demos import co.paralleluniverse.fibers.Suspendable import com.google.common.net.HostAndPort import com.r3corda.contracts.CommercialPaper -import com.r3corda.contracts.cash.cashBalances +import com.r3corda.contracts.asset.cashBalances import com.r3corda.contracts.testing.fillWithSomeTestCash import com.r3corda.core.contracts.* import com.r3corda.core.crypto.Party @@ -11,7 +11,6 @@ import com.r3corda.core.crypto.SecureHash import com.r3corda.core.crypto.generateKeyPair import com.r3corda.core.days import com.r3corda.core.logElapsedTime -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.node.NodeInfo import com.r3corda.core.node.services.ServiceType import com.r3corda.core.protocols.ProtocolLogic @@ -31,13 +30,13 @@ import com.r3corda.protocols.NotaryProtocol import com.r3corda.protocols.TwoPartyTradeProtocol import com.typesafe.config.ConfigFactory import joptsimple.OptionParser -import joptsimple.OptionSet import java.nio.file.Files import java.nio.file.Path import java.nio.file.Paths import java.security.PublicKey import java.time.Instant import java.util.* +import java.util.concurrent.CountDownLatch import kotlin.system.exitProcess import kotlin.test.assertEquals @@ -65,16 +64,29 @@ enum class Role { // And this is the directory under the current working directory where each node will create its own server directory, // which holds things like checkpoints, keys, databases, message logs etc. -val DIRNAME = "trader-demo" +val DEFAULT_BASE_DIRECTORY = "./build/trader-demo" fun main(args: Array) { + exitProcess(runTraderDemo(args)) +} + +fun runTraderDemo(args: Array): Int { val parser = OptionParser() val roleArg = parser.accepts("role").withRequiredArg().ofType(Role::class.java).required() val myNetworkAddress = parser.accepts("network-address").withRequiredArg().defaultsTo("localhost") val theirNetworkAddress = parser.accepts("other-network-address").withRequiredArg().defaultsTo("localhost") + val apiNetworkAddress = parser.accepts("api-address").withRequiredArg().defaultsTo("localhost") + val baseDirectoryArg = parser.accepts("base-directory").withRequiredArg().defaultsTo(DEFAULT_BASE_DIRECTORY) + + val options = try { + parser.parse(*args) + } catch (e: Exception) { + println(e.message) + printHelp(parser) + return 1 + } - val options = parseOptions(args, parser) val role = options.valueOf(roleArg)!! val myNetAddr = HostAndPort.fromString(options.valueOf(myNetworkAddress)).withDefaultPort( @@ -89,6 +101,9 @@ fun main(args: Array) { Role.SELLER -> 31337 } ) + val apiNetAddr = HostAndPort.fromString(options.valueOf(apiNetworkAddress)).withDefaultPort(myNetAddr.port + 1) + + val baseDirectory = options.valueOf(baseDirectoryArg)!! // Suppress the Artemis MQ noise, and activate the demo logging. // @@ -96,7 +111,8 @@ fun main(args: Array) { // for protocols will change in future. BriefLogFormatter.initVerbose("+demo.buyer", "+demo.seller", "-org.apache.activemq") - val directory = Paths.get(DIRNAME, role.name.toLowerCase()) + val directory = Paths.get(baseDirectory, role.name.toLowerCase()) + println("Using base demo directory $directory") // Override the default config file (which you can find in the file "reference.conf") to give each node a name. val config = run { @@ -123,7 +139,7 @@ fun main(args: Array) { // be a single shared map service (this is analagous to the DNS seeds in Bitcoin). // // TODO: AbstractNode should write out the full NodeInfo object and we should just load it here. - val path = Paths.get(DIRNAME, Role.BUYER.name.toLowerCase(), "identity-public") + val path = Paths.get(baseDirectory, Role.BUYER.name.toLowerCase(), "identity-public") val party = Files.readAllBytes(path).deserialize() advertisedServices = emptySet() cashIssuer = party @@ -132,7 +148,7 @@ fun main(args: Array) { // And now construct then start the node object. It takes a little while. val node = logElapsedTime("Node startup") { - Node(directory, myNetAddr, config, networkMapId, advertisedServices).setup().start() + Node(directory, myNetAddr, apiNetAddr, config, networkMapId, advertisedServices).setup().start() } // TODO: Replace with a separate trusted cash issuer @@ -146,21 +162,13 @@ fun main(args: Array) { if (role == Role.BUYER) { runBuyer(node, amount) } else { - runSeller(myNetAddr, node, theirNetAddr, amount) + runSeller(node, amount, cashIssuer) } + + return 0 } -fun parseOptions(args: Array, parser: OptionParser): OptionSet { - try { - return parser.parse(*args) - } catch (e: Exception) { - println(e.message) - println("Please refer to the documentation in docs/build/index.html to learn how to run the demo.") - exitProcess(1) - } -} - -fun runSeller(myNetAddr: HostAndPort, node: Node, theirNetAddr: HostAndPort, amount: Amount>) { +private fun runSeller(node: Node, amount: Amount>, otherSide: Party) { // The seller will sell some commercial paper to the buyer, who will pay with (self issued) cash. // // The CP sale transaction comes with a prospectus PDF, which will tag along for the ride in an @@ -179,15 +187,14 @@ fun runSeller(myNetAddr: HostAndPort, node: Node, theirNetAddr: HostAndPort, amo it.second.get() } } else { - val otherSide = ArtemisMessagingService.makeRecipient(theirNetAddr) - val seller = TraderDemoProtocolSeller(myNetAddr, otherSide, amount) + val seller = TraderDemoProtocolSeller(otherSide, amount) node.smm.add("demo.seller", seller).get() } node.stop() } -fun runBuyer(node: Node, amount: Amount>) { +private fun runBuyer(node: Node, amount: Amount>) { // Buyer will fetch the attachment from the seller automatically when it resolves the transaction. // For demo purposes just extract attachment jars when saved to disk, so the user can explore them. val attachmentsPath = (node.storage.attachments as NodeAttachmentService).let { @@ -195,75 +202,64 @@ fun runBuyer(node: Node, amount: Amount>) { it.storePath } - val future = if (node.isPreviousCheckpointsPresent) { - val (@Suppress("UNUSED_VARIABLE") buyer, future) = node.smm.findStateMachines(TraderDemoProtocolBuyer::class.java).single() - future - } else { + // Self issue some cash. + // + // TODO: At some point this demo should be extended to have a central bank node. + node.services.fillWithSomeTestCash(3000.DOLLARS, node.info.identity) + + // Wait around until a node asks to start a trade with us. In a real system, this part would happen out of band + // via some other system like an exchange or maybe even a manual messaging system like Bloomberg. But for the + // next stage in our building site, we will just auto-generate fake trades to give our nodes something to do. + // + // As the seller initiates the two-party trade protocol, here, we will be the buyer. + node.services.networkService.addMessageHandler("$DEMO_TOPIC.0") { message, registration -> // We use a simple scenario-specific wrapper protocol to make things happen. - val buyer = TraderDemoProtocolBuyer(attachmentsPath, node.info.identity, amount) + val otherSide = message.data.deserialize() + val buyer = TraderDemoProtocolBuyer(otherSide, attachmentsPath, amount) node.smm.add("demo.buyer", buyer) } - future.get() // This thread will halt forever here. + CountDownLatch(1).await() // Prevent the application from terminating } // We create a couple of ad-hoc test protocols that wrap the two party trade protocol, to give us the demo logic. val DEMO_TOPIC = "initiate.demo.trade" -class TraderDemoProtocolBuyer(private val attachmentsPath: Path, - val notary: Party, - val amount: Amount>) : ProtocolLogic() { - companion object { - object WAITING_FOR_SELLER_TO_CONNECT : ProgressTracker.Step("Waiting for seller to connect to us") +private class TraderDemoProtocolBuyer(val otherSide: Party, + private val attachmentsPath: Path, + val amount: Amount>, + override val progressTracker: ProgressTracker = ProgressTracker(STARTING_BUY)) : ProtocolLogic() { - object STARTING_BUY : ProgressTracker.Step("Seller connected, purchasing commercial paper asset") - } + object STARTING_BUY : ProgressTracker.Step("Seller connected, purchasing commercial paper asset") - override val progressTracker = ProgressTracker(WAITING_FOR_SELLER_TO_CONNECT, STARTING_BUY) + override val topic: String get() = DEMO_TOPIC @Suspendable override fun call() { - // Self issue some cash. - // - // TODO: At some point this demo should be extended to have a central bank node. - serviceHub.fillWithSomeTestCash(3000.DOLLARS, notary) + // The session ID disambiguates the test trade. + val sessionID = random63BitValue() + progressTracker.currentStep = STARTING_BUY + send(otherSide, 0, sessionID) - while (true) { - // Wait around until a node asks to start a trade with us. In a real system, this part would happen out of band - // via some other system like an exchange or maybe even a manual messaging system like Bloomberg. But for the - // next stage in our building site, we will just auto-generate fake trades to give our nodes something to do. - // - // As the seller initiates the two-party trade protocol, here, we will be the buyer. - try { - progressTracker.currentStep = WAITING_FOR_SELLER_TO_CONNECT - val hostname = receive(DEMO_TOPIC, 0).validate { it.withDefaultPort(Node.DEFAULT_PORT) } - val newPartnerAddr = ArtemisMessagingService.makeRecipient(hostname) + val notary = serviceHub.networkMapCache.notaryNodes[0] + val buyer = TwoPartyTradeProtocol.Buyer( + otherSide, + notary.identity, + amount, + CommercialPaper.State::class.java, + sessionID) - // The session ID disambiguates the test trade. - val sessionID = random63BitValue() - progressTracker.currentStep = STARTING_BUY - send(DEMO_TOPIC, newPartnerAddr, 0, sessionID) + // This invokes the trading protocol and out pops our finished transaction. + val tradeTX: SignedTransaction = subProtocol(buyer) + // TODO: This should be moved into the protocol itself. + serviceHub.recordTransactions(listOf(tradeTX)) - val notary = serviceHub.networkMapCache.notaryNodes[0] - val buyer = TwoPartyTradeProtocol.Buyer(newPartnerAddr, notary.identity, amount, - CommercialPaper.State::class.java, sessionID) + logger.info("Purchase complete - we are a happy customer! Final transaction is: " + + "\n\n${Emoji.renderIfSupported(tradeTX.tx)}") - // This invokes the trading protocol and out pops our finished transaction. - val tradeTX: SignedTransaction = subProtocol(buyer) - // TODO: This should be moved into the protocol itself. - serviceHub.recordTransactions(listOf(tradeTX)) - - logger.info("Purchase complete - we are a happy customer! Final transaction is: " + - "\n\n${Emoji.renderIfSupported(tradeTX.tx)}") - - logIssuanceAttachment(tradeTX) - logBalance() - - } catch(e: Exception) { - logger.error("Something went wrong whilst trading!", e) - } - } + logIssuanceAttachment(tradeTX) + logBalance() } private fun logBalance() { @@ -289,10 +285,9 @@ ${Emoji.renderIfSupported(cpIssuance)}""") } } -class TraderDemoProtocolSeller(val myAddress: HostAndPort, - val otherSide: SingleMessageRecipient, - val amount: Amount>, - override val progressTracker: ProgressTracker = TraderDemoProtocolSeller.tracker()) : ProtocolLogic() { +private class TraderDemoProtocolSeller(val otherSide: Party, + val amount: Amount>, + override val progressTracker: ProgressTracker = TraderDemoProtocolSeller.tracker()) : ProtocolLogic() { companion object { val PROSPECTUS_HASH = SecureHash.parse("decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9") @@ -310,11 +305,13 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort, fun tracker() = ProgressTracker(ANNOUNCING, SELF_ISSUING, TRADING) } + override val topic: String get() = DEMO_TOPIC + @Suspendable override fun call() { progressTracker.currentStep = ANNOUNCING - val sessionID = sendAndReceive(DEMO_TOPIC, otherSide, 0, 0, myAddress).validate { it } + val sessionID = sendAndReceive(otherSide, 0, 0, serviceHub.storageService.myLegalIdentity).validate { it } progressTracker.currentStep = SELF_ISSUING @@ -379,3 +376,13 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort, } } + +private fun printHelp(parser: OptionParser) { + println(""" + Usage: trader-demo --role [BUYER|SELLER] [options] + Please refer to the documentation in docs/build/index.html for more info. + + """.trimIndent()) + parser.printHelpOn(System.out) +} + diff --git a/src/main/kotlin/com/r3corda/demos/api/InterestRateSwapAPI.kt b/src/main/kotlin/com/r3corda/demos/api/InterestRateSwapAPI.kt index 9197216da7..c5e3574360 100644 --- a/src/main/kotlin/com/r3corda/demos/api/InterestRateSwapAPI.kt +++ b/src/main/kotlin/com/r3corda/demos/api/InterestRateSwapAPI.kt @@ -1,15 +1,16 @@ package com.r3corda.demos.api import com.r3corda.contracts.InterestRateSwap +import com.r3corda.core.contracts.SignedTransaction +import com.r3corda.core.node.ServiceHub +import com.r3corda.core.node.services.linearHeadsOfType import com.r3corda.core.utilities.loggerFor import com.r3corda.demos.protocols.AutoOfferProtocol import com.r3corda.demos.protocols.ExitServerProtocol import com.r3corda.demos.protocols.UpdateBusinessDayProtocol -import com.r3corda.node.api.APIServer -import com.r3corda.node.api.ProtocolClassRef -import com.r3corda.node.api.StatesQuery import java.net.URI import java.time.LocalDate +import java.time.LocalDateTime import javax.ws.rs.* import javax.ws.rs.core.MediaType import javax.ws.rs.core.Response @@ -35,23 +36,23 @@ import javax.ws.rs.core.Response * or if the demodate or population of deals should be reset (will only work while persistence is disabled). */ @Path("irs") -class InterestRateSwapAPI(val api: APIServer) { +class InterestRateSwapAPI(val services: ServiceHub) { private val logger = loggerFor() private fun generateDealLink(deal: InterestRateSwap.State) = "/api/irs/deals/" + deal.common.tradeID private fun getDealByRef(ref: String): InterestRateSwap.State? { - val states = api.queryStates(StatesQuery.selectDeal(ref)) + val states = services.walletService.linearHeadsOfType().filterValues { it.state.data.ref == ref } return if (states.isEmpty()) null else { - val deals = api.fetchStates(states).values.map { it?.data as InterestRateSwap.State }.filterNotNull() + val deals = states.values.map { it.state.data } return if (deals.isEmpty()) null else deals[0] } } private fun getAllDeals(): Array { - val states = api.queryStates(StatesQuery.selectAllDeals()) - val swaps = api.fetchStates(states).values.map { it?.data as InterestRateSwap.State }.filterNotNull().toTypedArray() + val states = services.walletService.linearHeadsOfType() + val swaps = states.values.map { it.state.data }.toTypedArray() return swaps } @@ -64,7 +65,7 @@ class InterestRateSwapAPI(val api: APIServer) { @Path("deals") @Consumes(MediaType.APPLICATION_JSON) fun storeDeal(newDeal: InterestRateSwap.State): Response { - api.invokeProtocolSync(ProtocolClassRef(AutoOfferProtocol.Requester::class.java.name!!), mapOf("dealToBeOffered" to newDeal)) + services.invokeProtocolAsync(AutoOfferProtocol.Requester::class.java, newDeal).get() return Response.created(URI.create(generateDealLink(newDeal))).build() } @@ -84,10 +85,10 @@ class InterestRateSwapAPI(val api: APIServer) { @Path("demodate") @Consumes(MediaType.APPLICATION_JSON) fun storeDemoDate(newDemoDate: LocalDate): Response { - val priorDemoDate = api.serverTime().toLocalDate() + val priorDemoDate = fetchDemoDate() // Can only move date forwards if (newDemoDate.isAfter(priorDemoDate)) { - api.invokeProtocolSync(ProtocolClassRef(UpdateBusinessDayProtocol.Broadcast::class.java.name!!), mapOf("date" to newDemoDate)) + services.invokeProtocolAsync(UpdateBusinessDayProtocol.Broadcast::class.java, newDemoDate).get() return Response.ok().build() } val msg = "demodate is already $priorDemoDate and can only be updated with a later date" @@ -99,14 +100,14 @@ class InterestRateSwapAPI(val api: APIServer) { @Path("demodate") @Produces(MediaType.APPLICATION_JSON) fun fetchDemoDate(): LocalDate { - return api.serverTime().toLocalDate() + return LocalDateTime.now(services.clock).toLocalDate() } @PUT @Path("restart") @Consumes(MediaType.APPLICATION_JSON) fun exitServer(): Response { - api.invokeProtocolSync(ProtocolClassRef(ExitServerProtocol.Broadcast::class.java.name!!), mapOf("exitCode" to 83)) + services.invokeProtocolAsync(ExitServerProtocol.Broadcast::class.java, 83).get() return Response.ok().build() } } diff --git a/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt index c90561608c..de4f754fc1 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/AutoOfferProtocol.kt @@ -6,7 +6,6 @@ import com.google.common.util.concurrent.Futures import com.r3corda.core.contracts.DealState import com.r3corda.core.contracts.SignedTransaction import com.r3corda.core.crypto.Party -import com.r3corda.core.messaging.SingleMessageRecipient import com.r3corda.core.protocols.ProtocolLogic import com.r3corda.core.random63BitValue import com.r3corda.core.serialization.deserialize @@ -24,7 +23,8 @@ import com.r3corda.protocols.TwoPartyDealProtocol object AutoOfferProtocol { val TOPIC = "autooffer.topic" - data class AutoOfferMessage(val otherSide: SingleMessageRecipient, + data class AutoOfferMessage(val otherSide: Party, + val notary: Party, val otherSessionID: Long, val dealBeingOffered: DealState) object Handler { @@ -53,9 +53,7 @@ object AutoOfferProtocol { val autoOfferMessage = msg.data.deserialize() // Put the deal onto the ledger progressTracker.currentStep = DEALING - // TODO required as messaging layer does not currently queue messages that arrive before we expect them - Thread.sleep(100) - val seller = TwoPartyDealProtocol.Instigator(autoOfferMessage.otherSide, node.services.networkMapCache.notaryNodes.first(), + val seller = TwoPartyDealProtocol.Instigator(autoOfferMessage.otherSide, autoOfferMessage.notary, autoOfferMessage.dealBeingOffered, node.services.keyManagementService.freshKey(), autoOfferMessage.otherSessionID, progressTracker.getChildProgressTracker(DEALING)!!) val future = node.smm.add("${TwoPartyDealProtocol.DEAL_TOPIC}.seller", seller) // This is required because we are doing child progress outside of a subprotocol. In future, we should just wrap things like this in a protocol to avoid it @@ -68,7 +66,7 @@ object AutoOfferProtocol { } - class Requester(val dealToBeOffered: DealState) : ProtocolLogic() { + class Requester(val dealToBeOffered: DealState) : ProtocolLogic() { companion object { object RECEIVED : ProgressTracker.Step("Received API call") @@ -83,6 +81,7 @@ object AutoOfferProtocol { fun tracker() = ProgressTracker(RECEIVED, ANNOUNCING, DEALING) } + override val topic: String get() = TOPIC override val progressTracker = tracker() init { @@ -94,20 +93,17 @@ object AutoOfferProtocol { require(serviceHub.networkMapCache.notaryNodes.isNotEmpty()) { "No notary nodes registered" } val ourSessionID = random63BitValue() - val notary = serviceHub.networkMapCache.notaryNodes.first() + val notary = serviceHub.networkMapCache.notaryNodes.first().identity // need to pick which ever party is not us val otherParty = notUs(*dealToBeOffered.parties).single() - val otherNode = (serviceHub.networkMapCache.getNodeByLegalName(otherParty.name)) - requireNotNull(otherNode) { "Cannot identify other party " + otherParty.name + ", know about: " + serviceHub.networkMapCache.partyNodes.map { it.identity } } - val otherSide = otherNode!!.address progressTracker.currentStep = ANNOUNCING - send(TOPIC, otherSide, 0, AutoOfferMessage(serviceHub.networkService.myAddress, ourSessionID, dealToBeOffered)) + send(otherParty, 0, AutoOfferMessage(serviceHub.storageService.myLegalIdentity, notary, ourSessionID, dealToBeOffered)) progressTracker.currentStep = DEALING - val stx = subProtocol(TwoPartyDealProtocol.Acceptor(otherSide, notary.identity, dealToBeOffered, ourSessionID, progressTracker.getChildProgressTracker(DEALING)!!)) + val stx = subProtocol(TwoPartyDealProtocol.Acceptor(otherParty, notary, dealToBeOffered, ourSessionID, progressTracker.getChildProgressTracker(DEALING)!!)) return stx } - fun notUs(vararg parties: Party): List { + private fun notUs(vararg parties: Party): List { val notUsParties: MutableList = arrayListOf() for (party in parties) { if (serviceHub.storageService.myLegalIdentity != party) { diff --git a/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt index abf20e3809..5258e3dead 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/ExitServerProtocol.kt @@ -22,7 +22,7 @@ object ExitServerProtocol { object Handler { fun register(node: Node) { - node.net.addMessageHandler("${TOPIC}.0") { msg, registration -> + node.net.addMessageHandler("$TOPIC.0") { msg, registration -> // Just to validate we got the message if (enabled) { val message = msg.data.deserialize() @@ -37,20 +37,21 @@ object ExitServerProtocol { * This takes a Java Integer rather than Kotlin Int as that is what we end up with in the calling map and currently * we do not support coercing numeric types in the reflective search for matching constructors */ - class Broadcast(@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") val exitCode: Integer) : ProtocolLogic() { + class Broadcast(val exitCode: Int) : ProtocolLogic() { + + override val topic: String get() = TOPIC @Suspendable override fun call(): Boolean { if (enabled) { - val rc = exitCode.toInt() - val message = ExitMessage(rc) + val message = ExitMessage(exitCode) for (recipient in serviceHub.networkMapCache.partyNodes) { doNextRecipient(recipient, message) } // Sleep a little in case any async message delivery to other nodes needs to happen Strand.sleep(1, TimeUnit.SECONDS) - System.exit(rc) + System.exit(exitCode) } return enabled } @@ -60,10 +61,7 @@ object ExitServerProtocol { if (recipient.address is MockNetworkMapCache.MockAddress) { // Ignore } else { - // TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages - if (recipient.identity != serviceHub.storageService.myLegalIdentity) { - send(TOPIC, recipient.address, 0, message) - } + send(recipient.identity, 0, message) } } } diff --git a/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt b/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt index 452e315871..ce9884bce0 100644 --- a/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt +++ b/src/main/kotlin/com/r3corda/demos/protocols/UpdateBusinessDayProtocol.kt @@ -1,171 +1,52 @@ package com.r3corda.demos.protocols import co.paralleluniverse.fibers.Suspendable -import com.r3corda.contracts.InterestRateSwap -import com.r3corda.core.contracts.DealState -import com.r3corda.core.contracts.StateAndRef -import com.r3corda.core.contracts.TransactionState import com.r3corda.core.node.NodeInfo -import com.r3corda.core.node.services.linearHeadsOfType import com.r3corda.core.protocols.ProtocolLogic -import com.r3corda.core.random63BitValue import com.r3corda.core.serialization.deserialize import com.r3corda.core.utilities.ProgressTracker import com.r3corda.demos.DemoClock import com.r3corda.node.internal.Node import com.r3corda.node.services.network.MockNetworkMapCache -import com.r3corda.node.utilities.ANSIProgressRenderer -import com.r3corda.protocols.TwoPartyDealProtocol import java.time.LocalDate /** - * This is a very temporary, demo-oriented way of initiating processing of temporal events and is not - * intended as the way things will necessarily be done longer term + * This is a less temporary, demo-oriented way of initiating processing of temporal events */ object UpdateBusinessDayProtocol { val TOPIC = "businessday.topic" - class Updater(val date: LocalDate, val sessionID: Long, - override val progressTracker: ProgressTracker = Updater.tracker()) : ProtocolLogic() { - - companion object { - object FETCHING : ProgressTracker.Step("Fetching deals") - object ITERATING_DEALS : ProgressTracker.Step("Interating over deals") - object ITERATING_FIXINGS : ProgressTracker.Step("Iterating over fixings") - object FIXING : ProgressTracker.Step("Fixing deal") - - fun tracker() = ProgressTracker(FETCHING, ITERATING_DEALS, ITERATING_FIXINGS, FIXING) - } - - @Suspendable - override fun call(): Boolean { - // Get deals - progressTracker.currentStep = FETCHING - val dealStateRefs = serviceHub.walletService.linearHeadsOfType() - val otherPartyToDeals = dealStateRefs.values.groupBy { otherParty(it.state.data) } - - // TODO we need to process these in parallel to stop there being an ordering problem across more than two nodes - val sortedParties = otherPartyToDeals.keys.sortedBy { it.identity.name } - for (party in sortedParties) { - val sortedDeals = otherPartyToDeals[party]!!.sortedBy { it.state.data.ref } - for (deal in sortedDeals) { - progressTracker.currentStep = ITERATING_DEALS - processDeal(party, deal, date, sessionID) - } - } - return false - } - - // This assumes we definitely have one key or the other - fun otherParty(deal: DealState): NodeInfo { - val ourKeys = serviceHub.keyManagementService.keys.keys - return serviceHub.networkMapCache.getNodeByLegalName(deal.parties.single { !ourKeys.contains(it.owningKey) }.name)!! - } - - // TODO we should make this more object oriented when we can ask a state for it's contract - @Suspendable - fun processDeal(party: NodeInfo, deal: StateAndRef, date: LocalDate, sessionID: Long) { - val s = deal.state.data - when (s) { - is InterestRateSwap.State -> processInterestRateSwap(party, StateAndRef(TransactionState(s, deal.state.notary), deal.ref), date, sessionID) - } - } - - // TODO and this would move to the InterestRateSwap and cope with permutations of Fixed/Floating and Floating/Floating etc - @Suspendable - fun processInterestRateSwap(party: NodeInfo, deal: StateAndRef, date: LocalDate, sessionID: Long) { - var dealStateAndRef: StateAndRef? = deal - var nextFixingDate = deal.state.data.calculation.nextFixingDate() - while (nextFixingDate != null && !nextFixingDate.isAfter(date)) { - progressTracker.currentStep = ITERATING_FIXINGS - /* - * Note that this choice of fixed versus floating leg is simply to assign roles in - * the fixing protocol and doesn't infer roles or responsibilities in a business sense. - * One of the parties needs to take the lead in the coordination and this is a reliable deterministic way - * to do it. - */ - if (party.identity.name == deal.state.data.fixedLeg.fixedRatePayer.name) { - dealStateAndRef = nextFixingFloatingLeg(dealStateAndRef!!, party, sessionID) - } else { - dealStateAndRef = nextFixingFixedLeg(dealStateAndRef!!, party, sessionID) - } - nextFixingDate = dealStateAndRef?.state?.data?.calculation?.nextFixingDate() - } - } - - @Suspendable - private fun nextFixingFloatingLeg(dealStateAndRef: StateAndRef, party: NodeInfo, sessionID: Long): StateAndRef? { - progressTracker.setChildProgressTracker(FIXING, TwoPartyDealProtocol.Primary.tracker()) - progressTracker.currentStep = FIXING - - val myName = serviceHub.storageService.myLegalIdentity.name - val deal: InterestRateSwap.State = dealStateAndRef.state.data - val myOldParty = deal.parties.single { it.name == myName } - val keyPair = serviceHub.keyManagementService.toKeyPair(myOldParty.owningKey) - val participant = TwoPartyDealProtocol.Floater(party.address, sessionID, serviceHub.networkMapCache.notaryNodes[0], dealStateAndRef, - keyPair, - sessionID, progressTracker.getChildProgressTracker(FIXING)!!) - val result = subProtocol(participant) - return result.tx.outRef(0) - } - - @Suspendable - private fun nextFixingFixedLeg(dealStateAndRef: StateAndRef, party: NodeInfo, sessionID: Long): StateAndRef? { - progressTracker.setChildProgressTracker(FIXING, TwoPartyDealProtocol.Secondary.tracker()) - progressTracker.currentStep = FIXING - - val participant = TwoPartyDealProtocol.Fixer( - party.address, - serviceHub.networkMapCache.notaryNodes[0].identity, - dealStateAndRef, - sessionID, - progressTracker.getChildProgressTracker(FIXING)!!) - val result = subProtocol(participant) - return result.tx.outRef(0) - } - } - - data class UpdateBusinessDayMessage(val date: LocalDate, val sessionID: Long) + data class UpdateBusinessDayMessage(val date: LocalDate) object Handler { + fun register(node: Node) { - node.net.addMessageHandler("$TOPIC.0") { msg, registration -> - // Just to validate we got the message + node.net.addMessageHandler("${TOPIC}.0") { msg, registration -> val updateBusinessDayMessage = msg.data.deserialize() - if ((node.services.clock as DemoClock).updateDate(updateBusinessDayMessage.date)) { - val participant = Updater(updateBusinessDayMessage.date, updateBusinessDayMessage.sessionID) - node.smm.add("update.business.day", participant) - } + (node.services.clock as DemoClock).updateDate(updateBusinessDayMessage.date) } } } class Broadcast(val date: LocalDate, - override val progressTracker: ProgressTracker = Broadcast.tracker()) : ProtocolLogic() { + override val progressTracker: ProgressTracker = Broadcast.tracker()) : ProtocolLogic() { companion object { - object NOTIFYING : ProgressTracker.Step("Notifying peer") - object LOCAL : ProgressTracker.Step("Updating locally") { - override fun childProgressTracker(): ProgressTracker = Updater.tracker() - } + object NOTIFYING : ProgressTracker.Step("Notifying peers") - fun tracker() = ProgressTracker(NOTIFYING, LOCAL) + fun tracker() = ProgressTracker(NOTIFYING) } - @Suspendable - override fun call(): Boolean { - val message = UpdateBusinessDayMessage(date, random63BitValue()) + override val topic: String get() = TOPIC + @Suspendable + override fun call(): Unit { + progressTracker.currentStep = NOTIFYING + val message = UpdateBusinessDayMessage(date) for (recipient in serviceHub.networkMapCache.partyNodes) { - progressTracker.currentStep = NOTIFYING doNextRecipient(recipient, message) } - if ((serviceHub.clock as DemoClock).updateDate(message.date)) { - progressTracker.currentStep = LOCAL - subProtocol(Updater(message.date, message.sessionID, progressTracker.getChildProgressTracker(LOCAL)!!)) - } - return true } @Suspendable @@ -173,10 +54,7 @@ object UpdateBusinessDayProtocol { if (recipient.address is MockNetworkMapCache.MockAddress) { // Ignore } else { - // TODO: messaging ourselves seems to trigger a bug for the time being and we continuously receive messages - if (recipient.identity != serviceHub.storageService.myLegalIdentity) { - send(TOPIC, recipient.address, 0, message) - } + send(recipient.identity, 0, message) } } } diff --git a/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt b/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt new file mode 100644 index 0000000000..24d09b7b09 --- /dev/null +++ b/src/main/kotlin/com/r3corda/demos/utilities/HttpUtils.kt @@ -0,0 +1,41 @@ +package com.r3corda.demos.utilities + +import okhttp3.* +import java.net.URL +import java.util.concurrent.TimeUnit + +/** + * A small set of utilities for making HttpCalls, aimed at demos. + */ +private val client by lazy { + OkHttpClient.Builder() + .connectTimeout(5, TimeUnit.SECONDS) + .readTimeout(60, TimeUnit.SECONDS).build(); +} + +fun putJson(url: URL, data: String) : Boolean { + val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), data) + return makeRequest(Request.Builder().url(url).put(body).build()) +} + +fun postJson(url: URL, data: String) : Boolean { + val body = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), data) + return makeRequest(Request.Builder().url(url).post(body).build()) +} + +fun uploadFile(url: URL, file: String) : Boolean { + val body = MultipartBody.Builder() + .setType(MultipartBody.FORM) + .addFormDataPart("rates", "example.rates.txt", RequestBody.create(MediaType.parse("text/plain"), file)) + .build(); + return makeRequest(Request.Builder().url(url).post(body).build()) +} + +private fun makeRequest(request: Request): Boolean { + val response = client.newCall(request).execute(); + + if (!response.isSuccessful) { + println("Could not fulfill HTTP request. Status Code: ${response.code()}. Message: ${response.body()}") + } + return response.isSuccessful +} \ No newline at end of file diff --git a/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry b/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry new file mode 100644 index 0000000000..279300f9f9 --- /dev/null +++ b/src/main/resources/META-INF/services/com.r3corda.core.node.CordaPluginRegistry @@ -0,0 +1,2 @@ +# Register a ServiceLoader service extending from com.r3corda.node.CordaPluginRegistry +com.r3corda.demos.IRSDemoPluginRegistry \ No newline at end of file