diff --git a/docs/build/html/_sources/consensus.txt b/docs/build/html/_sources/consensus.txt index 85e789acf9..8b2da03b7d 100644 --- a/docs/build/html/_sources/consensus.txt +++ b/docs/build/html/_sources/consensus.txt @@ -14,7 +14,7 @@ This article presents an initial model for addressing the **uniqueness** problem 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. +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: .. sourcecode:: kotlin @@ -67,16 +67,21 @@ 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:: 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). +.. 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. @@ -84,6 +89,31 @@ However, if the party is not also compelled to commit to the associated transact 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. +There will never be exact clock synchronisation between the party creating the transaction and the notary. +This is not only due to physics, network latencies etc but because between inserting the command and getting the +notary to sign there may be many other steps, like sending the transaction to other parties involved in the trade +as well, or even requesting human signoff. Thus the time observed by the notary may be quite different to the +time observed in step 1. + +For this reason, times in transactions are specified as time *windows*, not absolute times. Time windows can be +open-ended, i.e. specify only one of "before" and "after" or they can be fully bounded. If a time window needs to +be converted to an absolute time for e.g. display purposes, there is a utility method on ``Timestamp`` to +calculate the mid point - but in a distributed system there can never be "true time", only an approximation of it. + +In this way we express that the *true value* of the fact "the current time" is actually unknowable. Even when both before and +after times are included, the transaction could have occurred at any point between those two timestamps. Here +"occurrence" could mean the execution date, the value date, the trade date etc ... the notary doesn't care what precise +meaning the timestamp has to the contract. + +By creating a range that can be either closed or open at one end, we allow all of the following facts to be modelled: + +* This transaction occurred at some point after the given time (e.g. after a maturity event) +* This transaction occurred at any time before the given time (e.g. before a bankruptcy event) +* This transaction occurred at some point roughly around the given time (e.g. on a specific day) + +.. note:: It is assumed that the time feed for a notary is GPS/NaviStar time as defined by the atomic + clocks at the US Naval Observatory. This time feed is extremely accurate and available globally for free. + Running a Notary Service ------------------------ @@ -93,14 +123,29 @@ At present we have two basic implementations that store committed input states i - ``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: +Once a transaction is built and ready to be finalised, normally you would call ``FinalityProtocol`` passing in a +``SignedTransaction`` (including signatures from the participants) and a list of participants to notify. This requests a +notary signature if needed, and then sends a copy of the notarised transaction to all participants for them to store. +``FinalityProtocol`` delegates to ``NotaryProtocol.Client`` followed by ``BroadcastTransactionProtocol`` to do the +actual work of notarising and broadcasting the transaction. For example: + +.. sourcecode:: kotlin + + fun finaliseTransaction(serviceHub: ServiceHubInternal, ptx: TransactionBuilder, participants: Set) + : ListenableFuture { + // We conclusively cannot have all the signatures, as the notary has not signed yet + val tx = ptx.toSignedTransaction(checkSufficientSignatures = false) + // The empty set would be the trigger events, which are not used here + val protocol = FinalityProtocol(tx, emptySet(), participants) + return serviceHub.startProtocol("protocol.finalisation", protocol) + } + +To manually obtain a signature from a notary you can call ``NotaryProtocol.Client`` directly. 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 @@ -144,4 +189,6 @@ The protocol will: 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 +4. Record and distribute the final transaction to the participants so that everyone possesses the new state + +.. note:: Eventually this will be handled automatically on demand. \ No newline at end of file diff --git a/docs/build/html/_sources/contract-catalogue.txt b/docs/build/html/_sources/contract-catalogue.txt index 11f3b1302b..db52a161a2 100644 --- a/docs/build/html/_sources/contract-catalogue.txt +++ b/docs/build/html/_sources/contract-catalogue.txt @@ -1,4 +1,4 @@ -Platform contracts +Contract catalogue ================== There are a number of contracts supplied with Corda, which cover both core functionality (such as cash on ledger) and @@ -19,6 +19,16 @@ objects of the correct value are received by the beneficiary as part of the sett The cash contract supports issuing, moving and exiting (destroying) states. Note, however, that issuance cannot be part of the same transaction as other cash commands, in order to minimise complexity in balance verification. +Cash shares a common superclass, ``OnChainAsset``, with the Commodity contract. This implements common behaviour of +assets which can be issued, moved and exited on chain, with the subclasses handling asset-specific data types and +behaviour. + +Commodity +--------- + +The ``Commodity`` contract is an early stage example of a non-currency contract whose states implement the ``FungibleAsset`` +interface. This is used as a proof of concept for non-cash obligations. + Commercial Paper ---------------- diff --git a/docs/build/html/_sources/creating-a-cordapp.txt b/docs/build/html/_sources/creating-a-cordapp.txt new file mode 100644 index 0000000000..3831eb9c07 --- /dev/null +++ b/docs/build/html/_sources/creating-a-cordapp.txt @@ -0,0 +1,65 @@ +Creating a Cordapp +================== + +A Cordapp is an application that runs on the Corda platform using the platform APIs and plugin system. They are self +contained in separate JARs from the node server JAR that are created and distributed. + +App Plugins +----------- + +.. note:: Currently apps are only supported for JVM languages. + +To create an app plugin you must you must extend from `CordaPluginRegistry`_. The JavaDoc contains +specific details of the implementation, but you can extend the server in the following ways: + +1. Required protocols: Specify which protocols will be whitelisted for use in your web APIs. +2. Service plugins: Register your :ref:`services`. +3. Web APIs: You may register your own endpoints under /api/ of the built-in web server. +4. Static web endpoints: You may register your own static serving directories for serving web content. + +Services +-------- + +.. _services: + +Services are classes which are constructed after the node has started. It is provided a `ServiceHubInternal`_ which +allows a richer API than the `ServiceHub`_ exposed to contracts. It enables adding protocols, registering +message handlers and more. The service does not run in a separate thread, so the only entry point to the service is during +construction, where message handlers should be registered and threads started. + + +Starting Nodes +-------------- + +To use an app you must also have a node server. To create a node server run the gradle installTemplateNodes task. + +This will output the node JAR to ``build/libs/corda.jar`` and several sample/standard +node setups to ``build/nodes``. For now you can use the ``build/nodes/nodea`` configuration as a template. + +Each node server must have a ``node.conf`` file in the same directory as the node JAR file. After first +execution of the node server there will be many other configuration and persistence files created in this directory. + +.. note:: Outside of development environments do not store your node directories in the build folder. + +Installing Apps +------------------ + +Once you have created your app JAR you can install it to a node by adding it to ``/plugins/``. In this +case the ``node_dir`` is the location where your node server's JAR and configuration file is. + +.. note:: If the directory does not exist you can create it manually. + +Starting your Node +------------------ + +Now you have a node server with your app installed, you can run it by navigating to ```` and running + + java -jar corda.jar + +The plugin should automatically be registered and the configuration file used. + +.. warning:: If your working directory is not ```` your plugins and configuration will not be used. + +.. _CordaPluginRegistry: api/com.r3corda.core.node/-corda-plugin-registry/index.html +.. _ServiceHubInternal: api/com.r3corda.node.services.api/-service-hub-internal/index.html +.. _ServiceHub: api/com.r3corda.node.services.api/-service-hub/index.html \ No newline at end of file diff --git a/docs/build/html/_sources/data-model.txt b/docs/build/html/_sources/data-model.txt index ecc11db4c5..0ba274072d 100644 --- a/docs/build/html/_sources/data-model.txt +++ b/docs/build/html/_sources/data-model.txt @@ -2,13 +2,13 @@ Data model ========== This article covers the data model: how *states*, *transactions* and *code contracts* interact with each other and -how they are represented in the code. It doesn't attempt to give detailed design rationales or information on future +how they are represented in software. It doesn't attempt to give detailed design rationales or information on future design elements: please refer to the R3 wiki for background information. Overview -------- -We begin with the idea of a global ledger. In our model, although the ledger is shared, it is not always the case that +We begin with the idea of a global ledger. In our model although the ledger is shared, it is not always the case that transactions and ledger entries are globally visible. In cases where a set of transactions stays within a small subgroup of users it should be possible to keep the relevant data purely within that group. @@ -22,12 +22,15 @@ States contain arbitrary data, but they always contain at minimum a hash of the **contract code** file, which is a program expressed in JVM byte code that runs sandboxed inside a Java virtual machine. Contract code (or just "contracts" in the rest of this document) are globally shared pieces of business logic. +.. note:: In the current code dynamic loading of contracts is not implemented, so states currently point at + statically created object instances. This will change in the near future. + Contracts define a **verify function**, which is a pure function given the entire transaction as input. To be considered valid, the transaction must be **accepted** by the verify function of every contract pointed to by the input and output states. Beyond inputs and outputs, transactions may also contain **commands**, small data packets that -the platform does not interpret itself, but which can parameterise execution of the contracts. They can be thought of as +the platform does not interpret itself but which can parameterise execution of the contracts. They can be thought of as arguments to the verify function. Each command has a list of **public keys** associated with it. The platform ensures that the transaction is signed by every key listed in the commands before the contracts start to execute. Thus, a verify function can trust that all listed keys have signed the transaction but is responsible for verifying that any keys required @@ -35,10 +38,15 @@ for the transaction to be valid from the verify function's perspective are inclu may be random/identityless for privacy, or linked to a well known legal identity, for example via a *public key infrastructure* (PKI). +.. note:: Linkage of keys with identities via a PKI is only partially implemented in the current code. + Commands are always embedded inside a transaction. Sometimes, there's a larger piece of data that can be reused across many different transactions. For this use case, we have **attachments**. Every transaction can refer to zero or more -attachments by hash. Attachments are always ZIP/JAR files, which may contain arbitrary content. Contract code can then -access the attachments by opening them as a JarInputStream (this is temporary and will change later). +attachments by hash. Attachments are always ZIP/JAR files, which may contain arbitrary content. These files are +then exposed on the classpath and so can be opened by contract code in the same manner as any JAR resources +would be loaded. + +.. note:: Attachments must be opened explicitly in the current code. Note that there is nothing that explicitly binds together specific inputs, outputs, commands or attachments. Instead it's up to the contract code to interpret the pieces inside the transaction and ensure they fit together correctly. This @@ -48,13 +56,23 @@ Transactions may sometimes need to provide a contract with data from the outside prices, facts about events or the statuses of legal entities (e.g. bankruptcy), and so on. The providers of such facts are called **oracles** and they provide facts to the ledger by signing transactions that contain commands they recognise, or by creating signed attachments. The commands contain the fact and the signature shows agreement to that fact. -Time is also modelled as a fact, with the signature of a special kind of oracle called a **timestamping authority** (TSA). -A TSA signs a transaction if a pre-defined timestamping command in it defines a after/before time window that includes -"true time" (i.e. GPS time as calibrated to the US Naval Observatory). An oracle may prefer to generate a signed -attachment if the fact it's creating is relatively static and may be referred to over and over again. + +Time is also modelled as a fact, with the signature of a special kind of service called a **notary**. A notary is +a (very likely) decentralised service which fulfils the role that miners play in other blockchain systems: +notaries ensure only one transaction can consume any given output. Additionally they may verify a **timestamping +command** placed inside the transaction, which specifies a time window in which the transaction is considered +valid for notarisation. The time window can be open ended (i.e. with a start but no end or vice versa). In this +way transactions can be linked to the notary's clock. + +It is possible for a single Corda network to have multiple competing notaries. Each state points to the notary that +controls it. Whilst a single transaction may only consume states if they are all controlled by the same notary, +a special type of transaction is provided that moves a state (or set of states) from one notary to another. + +.. note:: Currently the platform code will not re-assign states to a single notary as needed for you, in case of + a mismatch. This is a future planned feature. As the same terminology often crops up in different distributed ledger designs, let's compare this to other -distributed ledger systems you may be familiar with. You can find more detailed design rationales for why the platform +systems you may be familiar with. You can find more detailed design rationales for why the platform differs from existing systems in `the R3 wiki `_, but to summarise, the driving factors are: @@ -62,7 +80,7 @@ but to summarise, the driving factors are: * Improved scalability vs Ethereum, as well as ability to keep parts of the transaction graph private (yet still uniquely addressable) * No reliance on proof of work * Re-use of existing sandboxing virtual machines -* Use of type safe GCd implementation languages. +* Use of type safe GCd implementation languages * Simplified auditing Comparison with Bitcoin @@ -77,8 +95,11 @@ Similarities: Given the same transaction, a contract's accept function always yields exactly the same result. * Bitcoin output scripts are parameterised by the input scripts in the spending transaction. This is somewhat similar to our notion of a *command*. +* Bitcoin has a global distributed notary service; that's the famous block chain. However, there is only one. Whilst + there is a notion of a "side chain", this isn't integrated with the core Bitcoin data model and thus adds large + amounts of additional complexity meaning in practice side chains are not used. * Bitcoin transactions, like ours, refer to the states they consume by using a (txhash, index) pair. The Bitcoin - protocol calls these "outpoints". In our prototype code they are known as ``StateRefs`` but the concept is identical. + protocol calls these "outpoints". In our code they are known as ``StateRefs`` but the concept is identical. * Bitcoin transactions have an associated timestamp (the time at which they are mined). Differences: @@ -92,8 +113,8 @@ Differences: * A Bitcoin script can only be given a fixed set of byte arrays as the input. This means there's no way for a contract to examine the structure of the entire transaction, which severely limits what contracts can do. * Our contracts are Turing-complete and can be written in any ordinary programming language that targets the JVM. -* Our transactions and contracts have to get their time from an attached timestamp rather than a block chain. This is - important given that we are currently considering block-free conflict resolution algorithms. +* Our transactions and contracts get their time from an attached timestamp rather than a block. This is + important given that we use block-free conflict resolution algorithms. The timestamp can be arbitrarily precise. * We use the term "contract" to refer to a bundle of business logic that may handle various different tasks, beyond transaction verification. For instance, currently our contracts also include code for creating valid transactions (this is often called "wallet code" in Bitcoin). @@ -252,7 +273,6 @@ to "reshape" outputs to useful/standardised sizes, for example, and to send outp back to their issuers for reissuance to "sever" long privacy-breaching chains. Finally, it should be noted that some of the issues described here are not really "cons" of -the UTXO model; they're just fundamental. -If you used many different anonymous accounts to preserve some privacy and then needed to -spend the contents of them all simultaneously, you'd hit the same problem, so it's not +the UTXO model; they're just fundamental. If you used many different anonymous accounts to preserve some privacy +and then needed to spend the contents of them all simultaneously, you'd hit the same problem, so it's not something that can be trivially fixed with data model changes. diff --git a/docs/build/html/_sources/event-scheduling.txt b/docs/build/html/_sources/event-scheduling.txt index 9c2cacfd92..94ed2b2189 100644 --- a/docs/build/html/_sources/event-scheduling.txt +++ b/docs/build/html/_sources/event-scheduling.txt @@ -7,7 +7,7 @@ Event scheduling ================ -This article explains our experimental approach to modelling time based events in code. It explains how a contract +This article explains our 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 @@ -28,7 +28,7 @@ due. If a contract state is consumed in the UTXO model, then what *was* the nex 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, +place when this event occurs. We already have a model for business processes in the form of :doc:`protocols `, 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. @@ -42,12 +42,11 @@ There are two main steps to implementing scheduled events: ``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. + wallet, it can expect to be queried for the next activity when committed to the wallet. * 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. + The important thing to remember is that in the current implementation, each node that is party to the transaction + will execute the same ``ProtocolLogic``, so it needs to establish roles in the business process based on the contract + state and the node it is running on. Each side will 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``. @@ -58,12 +57,14 @@ handler to help with obtaining a unqiue and secure random session. An example i 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. +``ScheduledActivity`` object returned. Be aware that this *only* happens if the wallet considers the state +"relevant", for instance, because the owner of the node also owns that state. States that your node happens to +encounter but which aren't related to yourself will not have any activities scheduled. An example ---------- -Let's take an example of the Interest Rate Swap fixings for our scheduled events. The first task is to implement the +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``. @@ -75,8 +76,6 @@ Let's take an example of the Interest Rate Swap fixings for our scheduled events 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) @@ -91,9 +90,10 @@ business process and to take on those roles. That ``ProtocolLogic`` will be han 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. +.. note:: This is a way to create a reference to the ProtocolLogic class and its constructor parameters to + instantiate. The reference 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 diff --git a/docs/build/html/_sources/index.txt b/docs/build/html/_sources/index.txt index 46da547db0..3ae4bec6d4 100644 --- a/docs/build/html/_sources/index.txt +++ b/docs/build/html/_sources/index.txt @@ -1,6 +1,9 @@ Welcome to the Corda repository! ================================ +.. warning:: This build of the docs is from the *master branch*, not a milestone release. It may not reflect the + current state of the code. + This documentation describes Corda, a proposed architecture for distributed ledgers, the vision for which is outlined in the `Corda Introductory Whitepaper`_. .. _`Corda Introductory Whitepaper`: _static/corda-introductory-whitepaper.pdf @@ -31,6 +34,7 @@ Read on to learn: transaction-data-types consensus messaging + creating-a-cordapp running-the-demos node-administration diff --git a/docs/build/html/_sources/inthebox.txt b/docs/build/html/_sources/inthebox.txt index 25ed8e2afa..3d2bf3b8b9 100644 --- a/docs/build/html/_sources/inthebox.txt +++ b/docs/build/html/_sources/inthebox.txt @@ -5,61 +5,26 @@ 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) +* Smart contracts, which you can find in the :doc:`contract-catalogue`. * 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. +* A simple REST API, and a web app demo that uses it to present a frontend for IRS trading. Some things it does not currently include but should gain later are: * Sandboxing, distribution or publication of smart contract code -* Database persistence * A user interface for administration -* Many other things 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 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 -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 -the issuing party for internal bookkeeping purposes. - -Cash states are *fungible* with each other (can be merged and split arbitrarily) if they use the same currency, -party and deposit reference. - -``CommercialPaper`` implements an asset with a *face value* denominated in a certain currency, which may be redeemed at -the issuing party after a certain time. Commercial paper states define the face value (e.g. $1000) and the time -at which they may be redeemed. The contract allows the paper to be issued, traded and redeemed. The commercial paper -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. +* There's currently no permissioning framework. +* Some privacy techniques aren't implemented yet. +* It uses an embedded SQL database and doesn't yet have connectivity support for mainstream SQL vendors (Oracle, + Postgres, MySQL, SQL Server etc). Kotlin ------ diff --git a/docs/build/html/_sources/messaging.txt b/docs/build/html/_sources/messaging.txt index 3c5cf56400..74cfabd871 100644 --- a/docs/build/html/_sources/messaging.txt +++ b/docs/build/html/_sources/messaging.txt @@ -1,123 +1,49 @@ Networking and messaging ======================== -Although the platform does not currently provide a network backend, some preliminary interfaces are defined along with -an in-memory implementation provided for use by unit tests and other exploratory code. An implementation based on Apache -Kafka is also being developed, which should be sufficient for real use cases to be implemented in the short run, even -though in the long run a fully peer to peer protocol will be required. +Corda uses AMQP/1.0 over TLS between nodes which is currently implemented using Apache Artemis, an embeddable message +queue broker. Building on established MQ protocols gives us features like persistence to disk, automatic delivery +retries with backoff and dead-letter routing, security, large message streaming and so on. -This article quickly explains the basic networking interfaces in the code. +Artemis is hidden behind a thin interface that also has an in-memory only implementation suitable for use in +unit tests and visualisation tools. -Messaging vs networking ------------------------ +.. note:: A future version of Corda will allow the MQ broker to be split out of the main node and run as a + separate server. We may also support non-Artemis implementations via JMS, allowing the broker to be swapped + out for alternative implementations. -It is important to understand that the code expects any networking module to provide the following services: +There are multiple ways of interacting with the network. When writing an application you typically won't use the +messaging subsystem directly. Instead you will build on top of the :doc:`protocol framework `, +which adds a layer on top of raw messaging to manage multi-step protocols and let you think in terms of identities +rather than specific network endpoints. -- Persistent, reliable and secure delivery of complete messages. The module is expected to retry delivery if initial - attempts fail. -- Ability to send messages both 1:1 and 1:many, where 'many' may mean the entire group of network users. +Messaging types +--------------- -The details of how this is achieved are not exposed to the rest of the code. - -Interfaces ----------- - -The most important interface is called ``MessagingService`` and is defined in the ``core/messaging/Messaging.kt`` file. -It declares an interface with the following operations: - -- ``addMessageHandler(topic: String, executor: Executor, callback: (Message, MessageHandlerRegistration) -> Unit)`` -- ``createMessage(topic: String, data: ByteArray): Message`` -- ``send(message: Message, targetRecipients: MessageRecipients)`` -- ``stop()`` - -along with a few misc others that are not important enough to discuss here. - -A *topic* is simply a string that identifies the kind of message that is being sent. When a message is received, the -topic is compared exactly to the list of registered message handlers and if it matches, the callback is invoked. -Adding a handler returns a ``MessageHandlerRegistration`` object that can be used to remove the handler, and that -registration object is also passed to each invocation to simplify the case where a handler wishes to remove itself. - -Some helper functions are also provided that simplify the process of sending a message by using Kryo serialisation, and -registering one-shot handlers that remove themselves once they finished running, but those don't need to be implemented -by network module authors themselves. - -Destinations are represented using opaque classes (i.e. their contents are defined by the implementation). The -``MessageRecipients`` interface represents any possible set of recipients: it's used when a piece of code doesn't -care who is going to get a message, just that someone does. The ``SingleMessageRecipient`` interface inherits from -``MessageRecipients`` and represents a handle to some specific individual receiver on the network. Whether they are -identified by IP address, public key, message router ID or some other kind of address is not exposed at this level. -``MessageRecipientGroup`` is not used anywhere at the moment but represents multiple simultaneous recipients. And -finally ``AllPossibleRecipients`` is used for network wide broadcast. It's also unused right now, outside of unit tests. - -In memory implementation ------------------------- - -To ease unit testing of business logic, a simple in-memory messaging service is provided. To access this you can inherit -your test case class from the ``TestWithInMemoryNetwork`` class. This provides a few utility methods to help test -code that involves message passing. - -You can run a mock network session in one of two modes: - -- Manually "pumped" -- Automatically pumped with background threads - -"Pumping" is the act of telling a mock network node to pop a message off its queue and process it. Typically you want -unit tests to be fast, repeatable and you want to be able to insert your own changes into the middle of any given -message sequence. This is what the manual mode is for. In this mode, all logic runs on the same thread (the thread -running the unit tests). You can create and use a node like this: - -.. container:: codeset - - .. sourcecode:: kotlin - - val (aliceAddr, aliceNode) = makeNode(inBackground = false) - val (bobAddr, bobNode) = makeNode(false) - - aliceNode.send("test.topic", aliceAddr, "foo") - bobNode.pump(blocking = false) - -.. note:: Currently only Kotlin examples are available for networking and protocol state machines. Java examples may - follow later. Naming arguments in Kotlin like above is optional but sometimes useful to make code examples clearer. - -The above code won't actually do anything because no message handler is registered for "test.topic" so the message will -go into a holding area. If/when we add a handler that can accept test.topic, the message will be delivered then. - -Sometimes you don't want to have to call the pump method over and over again. You can use the ``runNetwork { .. }`` -construct to fix this: any code inside the block will be run, and then all nodes you created will be pumped over and -over until all of them have reported that they have no work left to do. This means any ping-pongs of messages will -be run until everything settles. - -You can see more examples of how to use this in the file ``InMemoryMessagingTests.kt``. - -If you specify ``inBackground = true`` to ``makeNode`` then each node will create its own background thread which will -sit around waiting for messages to be delivered. Handlers will then be invoked on that background thread. This is a -more difficult style of programming that can be used to increase the realism of the unit tests by ensuring multiple -nodes run in parallel, just as they would on a real network spread over multiple machines. +Every ``Message`` object has an associated *topic* and may have a *session ID*. These are wrapped in a ``TopicSession``. +An implementation of ``MessagingService`` can be used to create messages and send them. You can get access to the +messaging service via the ``ServiceHub`` object that is provided to your app. Endpoints on the network are +identified at the lowest level using ``SingleMessageRecipient`` which may be e.g. an IP address, or in future +versions perhaps a routing path through the network. Network Map Service ------------------- Supporting the messaging layer is a network map service, which is responsible for tracking public nodes on the network. -Nodes have an internal component, the network map cache, which contains a copy of the network map. When a node starts up -its cache fetches a copy of the full network map, and requests to be notified of changes. The node then registers itself -with the network map service, and the service notifies subscribers that a new node has joined the network. Nodes do not -automatically deregister themselves, so (for example) nodes going offline briefly for maintenance are retained in the -network map, and messages for them will be queued, minimising disruption. -Nodes submit signed changes to the map service, which then forwards them on to nodes which have requested to be notified -of changes. This process achieves basic consensus of the overall network map, although currently it has no formal -process for identifying or recovering from issues such as network outages. Later versions are planned to address this. +Nodes have an internal component, the network map cache, which contains a copy of the network map (which is just a +document). When a node starts up its cache fetches a copy of the full network map, and requests to be notified of +changes. The node then registers itself with the network map service, and the service notifies subscribers that a new +node has joined the network. Nodes do not automatically deregister themselves, so (for example) nodes going offline +briefly for maintenance are retained in the network map, and messages for them will be queued, minimising disruption. -Registration change notifications contain a serial number, which indicates their relative ordering, similar to the -serial number on DNS records. These numbers must increase with each change, but are not expected to be sequential. -Changes are then signed by the party whom the node represents to confirm the association between party and node. -The change, signature and public key are then sent to the network map service, which verifies the signature and then -updates the network map accordingly. +Nodes submit signed changes to the map service, which then forwards update notifications on to nodes which have +requested to be notified of changes. -The network map cache currently supports: +The network map currently supports: * Looking up nodes by service * Looking up node for a party * Suggesting a node providing a specific service, based on suitability for a contract and parties, for example suggesting -an appropriate interest rates oracle for a interest rate swap contract. Currently no recommendation logic is in place -(the code simply picks the first registered node that supports the required service), however. + an appropriate interest rates oracle for a interest rate swap contract. Currently no recommendation logic is in place. + The code simply picks the first registered node that supports the required service. \ No newline at end of file diff --git a/docs/build/html/_sources/node-administration.txt b/docs/build/html/_sources/node-administration.txt index d83d75c4e1..32cb71f587 100644 --- a/docs/build/html/_sources/node-administration.txt +++ b/docs/build/html/_sources/node-administration.txt @@ -9,7 +9,7 @@ Monitoring your node Like most Java servers, the node exports various useful metrics and management operations via the industry-standard `JMX infrastructure `_. JMX is a standard API -for registering so-called _MBeans_ ... objects whose properties and methods are intended for server management. It does +for registering so-called *MBeans* ... objects whose properties and methods are intended for server management. It does not require any particular network protocol for export. So this data can be exported from the node in various ways: some monitoring systems provide a "Java Agent", which is essentially a JVM plugin that finds all the MBeans and sends them out to a statistics collector over the network. For those systems, follow the instructions provided by the vendor. diff --git a/docs/build/html/_sources/oracles.txt b/docs/build/html/_sources/oracles.txt index 2314111be5..06f5843818 100644 --- a/docs/build/html/_sources/oracles.txt +++ b/docs/build/html/_sources/oracles.txt @@ -10,12 +10,8 @@ Writing oracle services This article covers *oracles*: network services that link the ledger to the outside world by providing facts that affect the validity of transactions. -The current prototype includes two oracles: - -1. A timestamping service -2. An interest rate fixing service - -We will examine the similarities and differences in their design, whilst covering how the oracle concept works. +The current prototype includes an example oracle that provides an interest rate fixing service. It is used by the +IRS trading demo app. Introduction ------------ @@ -53,10 +49,12 @@ When a fact is encoded in a command, it is embedded in the transaction itself. T the entire transaction. The oracle's signature is valid only for that transaction, and thus even if a fact (like a stock price) does not change, every transaction that incorporates that fact must go back to the oracle for signing. -When a fact is encoded as an attachment, it is a separate object to the transaction which is referred to by hash. +When a fact is encoded as an attachment, it is a separate object to the transaction and is referred to by hash. Nodes download attachments from peers at the same time as they download transactions, unless of course the node has already seen that attachment, in which case it won't fetch it again. Contracts have access to the contents of -attachments and attachments can be digitally signed (in future). +attachments when they run. + +.. note:: Currently attachments do not support digital signing, but this is a planned feature. As you can see, both approaches share a few things: they both allow arbitrary binary data to be provided to transactions (and thus contracts). The primary difference is whether the data is a freely reusable, standalone object or whether it's @@ -74,79 +72,34 @@ Here's a quick way to decide which approach makes more sense for your data sourc * Is your data *intended for human consumption*, like a PDF of legal prose, or an Excel spreadsheet? If yes, use an attachment. -Asserting continuously varying data that is publicly known ----------------------------------------------------------- +Asserting continuously varying data +----------------------------------- -Let's look at the timestamping oracle that can be found in the ``TimestamperService`` class. This is an example of -an oracle that uses a command because the current time is a constantly changing fact that everybody knows. +.. note:: A future version of the platform will include a complete tutorial on implementing this type of oracle. -The most obvious way to implement such a service would be: +Let's look at the interest rates oracle that can be found in the ``NodeInterestRates`` file. This is an example of +an oracle that uses a command because the current interest rate fix is a constantly changing fact. -1. The creator of the transaction that depends on the time reads their local clock -2. They insert a command with that time into the transaction -3. They then send it to the oracle for signing. +The obvious way to implement such a service is like this: -But this approach has a problem. There will never be exact clock synchronisation between the party creating the -transaction and the oracle. This is not only due to physics, network latencies etc but because between inserting the -command and getting the oracle to sign there may be many other steps, like sending the transaction to other parties -involved in the trade as well, or even requesting human signoff. Thus the time observed by the oracle may be quite -different to the time observed in step 1. This problem can occur any time an oracle attests to a constantly changing -value. +1. The creator of the transaction that depends on the interest rate sends it to the oracle. +2. The oracle inserts a command with the rate and signs the transaction. +3. The oracle sends it back. -.. note:: It is assumed that "true time" for a timestamping oracle means GPS/NaviStar time as defined by the atomic - clocks at the US Naval Observatory. This time feed is extremely accurate and available globally for free. +But this has a problem - it would mean that the oracle has to be the first entity to sign the transaction, which might impose +ordering constraints we don't want to deal with (being able to get all parties to sign in parallel is a very nice thing). +So the way we actually implement it is like this: -We fix it by including explicit tolerances in the command, which is defined like this: - -.. sourcecode:: kotlin - - data class TimestampCommand(val after: Instant?, val before: Instant?) : CommandData - init { - if (after == null && before == null) - throw IllegalArgumentException("At least one of before/after must be specified") - if (after != null && before != null) - check(after <= before) - } - } - -This defines a class that has two optional fields: before and after, along with a constructor that imposes a couple -more constraints that cannot be expressed in the type system, namely, that "after" actually is temporally after -"before", and that at least one bound must be present. A timestamp command that doesn't contain anything is illegal. - -Thus we express that the *true value* of the fact "the current time" is actually unknowable. Even when both before and -after times are included, the transaction could have occurred at any point between those two timestamps. In this case -"occurrence" could mean the execution date, the value date, the trade date etc ... the oracle doesn't care what precise -meaning the timestamp has to the contract. - -By creating a range that can be either closed or open at one end, we allow all of the following facts to be modelled: - -* This transaction occurred at some point after the given time (e.g. after a maturity event) -* This transaction occurred at any time before the given time (e.g. before a bankruptcy event) -* This transaction occurred at some point roughly around the given time (e.g. on a specific day) +1. The creator of the transaction that depends on the interest rate asks for the current rate. They can abort at this point + if they want to. +2. They insert a command with that rate and the time it was obtained into the transaction. +3. They then send it to the oracle for signing, along with everyone else in parallel. The oracle checks that the command + has correct data for the asserted time, and signs if so. This same technique can be adapted to other types of oracle. -Asserting occasionally varying data that is not publicly known --------------------------------------------------------------- - -Sometimes you may want a fact that changes, but is not entirely continuous. Additionally the exact value may not be -public, or may only be semi-public (e.g. easily available to some entities on the network but not all). An example of -this would be a LIBOR interest rate fix. - -In this case, the following design can be used. The oracle service provides a query API which returns the current value, -and a signing service that signs a transaction if the data in the command matches the answer being returned by the -query API. Probably the query response contains some sort of timestamp as well, so the service can recognise values -that were true in the past but no longer are (this is arguably a part of the fact being asserted). - -Because the signature covers the transaction, and transactions may end up being forwarded anywhere, the fact itself -is independently checkable. However, this approach can be useful when the data itself costs money, because the act -of issuing the signature in the first place can be charged for (e.g. by requiring the submission of a fresh -``Cash.State`` that has been re-assigned to a key owned by the oracle service). Because the signature covers the -*transaction* and not only the *fact*, this allows for a kind of weak pseudo-DRM over data feeds. Whilst a smart -contract could in theory include a transaction parsing and signature checking library, writing a contract in this way -would be conclusive evidence of intent to disobey the rules of the service (*res ipsa loquitur*). In an environment -where parties are legally identifiable, usage of such a contract would by itself be sufficient to trigger some sort of -punishment. +The oracle consists of a core class that implements the query/sign operations (for easy unit testing), and then a separate +class that binds it to the network layer. Here is an extract from the ``NodeService.Oracle`` class and supporting types: @@ -167,20 +120,15 @@ Here is an extract from the ``NodeService.Oracle`` class and supporting types: Because the fix contains a timestamp (the ``forDay`` field), there can be an arbitrary delay between a fix being requested via ``query`` and the signature being requested via ``sign``. -Implementing oracles in the framework -------------------------------------- +Pay-per-play oracles +-------------------- -Implementation involves the following steps: - -1. Defining a high level oracle class, that exposes the basic API operations. -2. Defining a lower level service class, that binds network messages to the API. -3. Defining a protocol using the :doc:`protocol-state-machines` framework to make it easy for a client to interact - with the oracle. -4. Constructing it (when advertised) in ``AbstractNode``. - -An example of how to do this can be found in the ``NodeInterestRates.Oracle``, ``NodeInterestRates.Service`` and -``RateFixProtocol`` classes. - -The exact details of how this code works will change in future, so for now consulting the protocols tutorial and the -code for the server-side oracles implementation will have to suffice. There will be more detail added once the -platform APIs have settled down. \ No newline at end of file +Because the signature covers the transaction, and transactions may end up being forwarded anywhere, the fact itself +is independently checkable. However, this approach can still be useful when the data itself costs money, because the act +of issuing the signature in the first place can be charged for (e.g. by requiring the submission of a fresh +``Cash.State`` that has been re-assigned to a key owned by the oracle service). Because the signature covers the +*transaction* and not only the *fact*, this allows for a kind of weak pseudo-DRM over data feeds. Whilst a smart +contract could in theory include a transaction parsing and signature checking library, writing a contract in this way +would be conclusive evidence of intent to disobey the rules of the service (*res ipsa loquitur*). In an environment +where parties are legally identifiable, usage of such a contract would by itself be sufficient to trigger some sort of +punishment. diff --git a/docs/build/html/_sources/protocol-state-machines.txt b/docs/build/html/_sources/protocol-state-machines.txt index bfcb0a9ca4..802ea563a7 100644 --- a/docs/build/html/_sources/protocol-state-machines.txt +++ b/docs/build/html/_sources/protocol-state-machines.txt @@ -102,27 +102,19 @@ We start by defining a wrapper that namespaces the protocol code, two functions of the protocol, and two classes that will contain the protocol definition. We also pick what data will be used by each side. +.. note:: The code samples in this tutorial are only available in Kotlin, but you can use any JVM language to + write them and the approach is the same. + .. container:: codeset .. sourcecode:: kotlin object TwoPartyTradeProtocol { - val TRADE_TOPIC = "platform.trade" + val TOPIC = "platform.trade" - fun runSeller(smm: StateMachineManager, timestampingAuthority: LegallyIdentifiableNode, - otherSide: SingleMessageRecipient, assetToSell: StateAndRef, price: Amount, - myKeyPair: KeyPair, buyerSessionID: Long): ListenableFuture { - val seller = Seller(otherSide, timestampingAuthority, assetToSell, price, myKeyPair, buyerSessionID) - smm.add("$TRADE_TOPIC.seller", seller) - return seller.resultFuture - } - - fun runBuyer(smm: StateMachineManager, timestampingAuthority: LegallyIdentifiableNode, - otherSide: SingleMessageRecipient, acceptablePrice: Amount, typeToBuy: Class, - sessionID: Long): ListenableFuture { - val buyer = Buyer(otherSide, timestampingAuthority.identity, acceptablePrice, typeToBuy, sessionID) - smm.add("$TRADE_TOPIC.buyer", buyer) - return buyer.resultFuture + class UnacceptablePriceException(val givenPrice: Amount) : Exception("Unacceptable price: $givenPrice") + class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() { + override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName" } // This object is serialised to the network and is the first protocol message the seller sends to the buyer. @@ -135,28 +127,24 @@ each side. class SignaturesFromSeller(val timestampAuthoritySig: DigitalSignature.WithKey, val sellerSig: DigitalSignature.WithKey) - class Seller(val otherSide: SingleMessageRecipient, - val timestampingAuthority: LegallyIdentifiableNode, - val assetToSell: StateAndRef, - val price: Amount, - val myKeyPair: KeyPair, - val buyerSessionID: Long) : ProtocolLogic() { + open class Seller(val otherSide: Party, + val notaryNode: NodeInfo, + val assetToSell: StateAndRef, + val price: Amount, + val myKeyPair: KeyPair, + val buyerSessionID: Long, + override val progressTracker: ProgressTracker = Seller.tracker()) : ProtocolLogic() { @Suspendable override fun call(): SignedTransaction { TODO() } } - class UnacceptablePriceException(val givenPrice: Amount) : Exception() - class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() { - override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName" - } - - class Buyer(val otherSide: SingleMessageRecipient, - val timestampingAuthority: Party, - val acceptablePrice: Amount, - val typeToBuy: Class, - val sessionID: Long) : ProtocolLogic() { + open class Buyer(val otherSide: Party, + val notary: Party, + val acceptablePrice: Amount, + val typeToBuy: Class, + val sessionID: Long) : ProtocolLogic() { @Suspendable override fun call(): SignedTransaction { TODO() @@ -166,52 +154,41 @@ each side. Let's unpack what this code does: -- It defines a several classes nested inside the main ``TwoPartyTradeProtocol`` singleton, and a couple of methods, one - to run the buyer side of the protocol and one to run the seller side. Some of the classes are simply protocol messages. +- It defines a several classes nested inside the main ``TwoPartyTradeProtocol`` singleton. Some of the classes + are simply protocol messages or exceptions. The other two represent the buyer and seller side of the protocol. - It defines the "trade topic", which is just a string that namespaces this protocol. The prefix "platform." is reserved - by the DLG, but you can define your own protocols using standard Java-style reverse DNS notation. -- The ``runBuyer`` and ``runSeller`` methods take a number of parameters that specialise the protocol for this run, - use them to construct a ``Buyer`` or ``Seller`` object respectively, and then add the new instances to the - ``StateMachineManager``. The purpose of this class is described below. The ``smm.add`` method takes a logger name as - the first parameter, this is just a standard JDK logging identifier string, and the instance to add. + by Corda, but you can define your own protocol namespaces using standard Java-style reverse DNS notation. Going through the data needed to become a seller, we have: -- ``timestampingAuthority: LegallyIdentifiableNode`` - a reference to a node on the P2P network that acts as a trusted - timestamper. The use of timestamping is described in :doc:`data-model`. - ``otherSide: SingleMessageRecipient`` - the network address of the node with which you are trading. +- ``notaryNode: NodeInfo`` - the entry in the network map for the chosen notary. See ":doc:`consensus`" for more + information on notaries. - ``assetToSell: StateAndRef`` - a pointer to the ledger entry that represents the thing being sold. -- ``price: Amount`` - the agreed on price that the asset is being sold for. +- ``price: Amount`` - the agreed on price that the asset is being sold for (without an issuer constraint). - ``myKeyPair: KeyPair`` - the key pair that controls the asset being sold. It will be used to sign the transaction. - ``buyerSessionID: Long`` - a unique number that identifies this trade to the buyer. It is expected that the buyer - knows that the trade is going to take place and has sent you such a number already. (This field may go away in a future - iteration of the framework) + knows that the trade is going to take place and has sent you such a number already. -.. note:: Session IDs keep different traffic streams separated, so for security they must be large and random enough - to be unguessable. 63 bits is good enough. +.. note:: Session IDs will be automatically handled in a future version of the framework. And for the buyer: -- ``acceptablePrice: Amount`` - the price that was agreed upon out of band. If the seller specifies a price less than - or equal to this, then the trade will go ahead. +- ``acceptablePrice: Amount`` - the price that was agreed upon out of band. If the seller specifies + a price less than or equal to this, then the trade will go ahead. - ``typeToBuy: Class`` - the type of state that is being purchased. This is used to check that the sell side of the protocol isn't trying to sell us the wrong thing, whether by accident or on purpose. - ``sessionID: Long`` - the session ID that was handed to the seller in order to start the protocol. -The run methods return a ``ListenableFuture`` that will complete when the protocol has finished. +Alright, so using this protocol shouldn't be too hard: in the simplest case we can just create a Buyer or Seller +with the details of the trade, depending on who we are. We then have to start the protocol in some way. Just +calling the ``call`` function ourselves won't work: instead we need to ask the framework to start the protocol for +us. More on that in a moment. -Alright, so using this protocol shouldn't be too hard: in the simplest case we can just pass in the details of the trade -to either runBuyer or runSeller, depending on who we are, and then call ``.get()`` on resulting object to -block the calling thread until the protocol has finished. Or we could register a callback on the returned future that -will be invoked when it's done, where we could e.g. update a user interface. +Suspendable functions +--------------------- -Finally, we define a couple of exceptions, and two classes that will be used as a protocol message called -``SellerTradeInfo`` and ``SignaturesFromSeller``. - -Suspendable methods -------------------- - -The ``call`` method of the buyer/seller classes is marked with the ``@Suspendable`` annotation. What does this mean? +The ``call`` function of the buyer/seller classes is marked with the ``@Suspendable`` annotation. What does this mean? As mentioned above, our protocol framework will at points suspend the code and serialise it to disk. For this to work, any methods on the call stack must have been pre-marked as ``@Suspendable`` so the bytecode rewriter knows to modify @@ -221,50 +198,52 @@ invoked, all methods on the stack must have been marked. If you forget, then in get a useful error message telling you which methods you didn't mark. The fix is simple enough: just add the annotation and try again. -.. note:: A future version of Java is likely to remove this pre-marking requirement completely. +.. note:: Java 9 is likely to remove this pre-marking requirement completely. -The state machine manager -------------------------- +Starting your protocol +---------------------- -The SMM is a class responsible for taking care of all running protocols in a node. It knows how to register handlers -with a ``MessagingService`` and iterate the right state machine when messages arrive. It provides the -send/receive/sendAndReceive calls that let the code request network interaction and it will store a serialised copy of -each state machine before it's suspended to wait for the network. +The ``StateMachineManager`` is the class responsible for taking care of all running protocols in a node. It knows +how to register handlers with the messaging system (see ":doc:`messaging`") and iterate the right state machine +when messages arrive. It provides the send/receive/sendAndReceive calls that let the code request network +interaction and it will save/restore serialised versions of the fiber at the right times. -To get a ``StateMachineManager``, you currently have to build one by passing in a ``ServiceHub`` and a thread or thread -pool which it can use. This will change in future so don't worry about the details of this too much: just check the -unit tests to see how it's done. +Protocols can be invoked in several ways. For instance, they can be triggered by scheduled events, +see ":doc:`event-scheduling`" to learn more about this. Or they can be triggered via the HTTP API. Or they can +be triggered directly via the Java-level node APIs from your app code. + +You request a protocol to be invoked by using the ``ServiceHub.invokeProtocolAsync`` method. This takes a +Java reflection ``Class`` object that describes the protocol class to use (in this case, either ``Buyer`` or ``Seller``). +It also takes a set of arguments to pass to the constructor. Because it's possible for protocol invocations to +be requested by untrusted code (e.g. a state that you have been sent), the types that can be passed into the +protocol are checked against a whitelist, which can be extended by apps themselves at load time. + +The process of starting a protocol returns a ``ListenableFuture`` that you can use to either block waiting for +the result, or register a callback that will be invoked when the result is ready. Implementing the seller ----------------------- -Let's implement the ``Seller.call`` method. This will be invoked by the platform when the protocol is started by the -``StateMachineManager``. +Let's implement the ``Seller.call`` method. This will be run when the protocol is invoked. .. container:: codeset .. sourcecode:: kotlin - val partialTX: SignedTransaction = receiveAndCheckProposedTransaction() - - // These two steps could be done in parallel, in theory. Our framework doesn't support that yet though. - val ourSignature = signWithOurKey(partialTX) - val tsaSig = subProtocol(TimestampingProtocol(timestampingAuthority, partialTX.txBits)) - - val stx: SignedTransaction = sendSignatures(partialTX, ourSignature, tsaSig) - - return stx + @Suspendable + override fun call(): SignedTransaction { + val partialTX: SignedTransaction = receiveAndCheckProposedTransaction() + val ourSignature: DigitalSignature.WithKey = signWithOurKey(partialTX) + val notarySignature = getNotarySignature(partialTX) + val result: SignedTransaction = sendSignatures(partialTX, ourSignature, notarySignature) + return result + } Here we see the outline of the procedure. We receive a proposed trade transaction from the buyer and check that it's -valid. Then we sign with our own key, request a timestamping authority to assert with another signature that the -timestamp in the transaction (if any) is valid, and finally we send back both our signature and the TSA's signature. -Finally, we hand back to the code that invoked the protocol the finished transaction in a couple of different forms. - -.. note:: ``ProtocolLogic`` classes can be composed together. Here, we see the use of the ``subProtocol`` method, which - is given an instance of ``TimestampingProtocol``. This protocol will run to completion and yield a result, almost - as if it's a regular method call. In fact, under the hood, all the ``subProtocol`` method does is pass the current - fiber object into the newly created object and then run ``call()`` on it ... so it basically _is_ just a method call. - This is where we can see the benefits of using continuations/fibers as a programming model. +valid. Then we sign with our own key and request a notary to assert with another signature that the +timestamp in the transaction (if any) is valid and there are no double spends, and send back both +our signature and the notaries signature. Finally, we hand back to the code that invoked the protocol the +finished transaction. Let's fill out the ``receiveAndCheckProposedTransaction()`` method. @@ -273,56 +252,48 @@ Let's fill out the ``receiveAndCheckProposedTransaction()`` method. .. sourcecode:: kotlin @Suspendable - open fun receiveAndCheckProposedTransaction(): SignedTransaction { + private fun receiveAndCheckProposedTransaction(): SignedTransaction { val sessionID = random63BitValue() // 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) maybeSTX.validate { // Check that the tx proposed by the buyer is valid. - val missingSigs = it.verify(throwIfSignaturesAreMissing = false) - if (missingSigs != setOf(myKeyPair.public, timestampingAuthority.identity.owningKey)) - throw SignatureException("The set of missing signatures is not as expected: $missingSigs") + val missingSigs: Set = it.verifySignatures(throwIfSignaturesAreMissing = false) + val expected = setOf(myKeyPair.public, notaryNode.identity.owningKey) + if (missingSigs != expected) + throw SignatureException("The set of missing signatures is not as expected: ${missingSigs.toStringsShort()} vs ${expected.toStringsShort()}") val wtx: WireTransaction = it.tx logger.trace { "Received partially signed transaction: ${it.id}" } - checkDependencies(it) + // Download and check all the things that this transaction depends on and verify it is contract-valid, + // even though it is missing signatures. + subProtocol(ResolveTransactionsProtocol(wtx, otherSide)) - // This verifies that the transaction is contract-valid, even though it is missing signatures. - serviceHub.verifyTransaction(wtx.toLedgerTransaction(serviceHub.identityService)) - - if (wtx.outputs.sumCashBy(myKeyPair.public) != price) - throw IllegalArgumentException("Transaction is not sending us the right amounnt of cash") - - // There are all sorts of funny games a malicious secondary might play here, we should fix them: - // - // - This tx may attempt to send some assets we aren't intending to sell to the secondary, if - // we're reusing keys! So don't reuse keys! - // - This tx may include output states that impose odd conditions on the movement of the cash, - // once we implement state pairing. - // - // but the goal of this code is not to be fully secure (yet), but rather, just to find good ways to - // express protocol state machines on top of the messaging layer. + if (wtx.outputs.map { it.data }.sumCashBy(myKeyPair.public).withoutIssuer() != price) + throw IllegalArgumentException("Transaction is not sending us the right amount of cash") return it } } -That's pretty straightforward. We generate a session ID to identify what's happening on the seller side, fill out +Let's break this down. We generate a session ID to identify what's happening on the seller side, fill out the initial protocol message, and then call ``sendAndReceive``. This function takes a few arguments: - The topic string that ensures the message is routed to the right bit of code in the other side's node. - The session IDs that ensure the messages don't get mixed up with other simultaneous trades. - The thing to send. It'll be serialised and sent automatically. -- Finally a type argument, which is the kind of object we're expecting to receive from the other side. +- Finally a type argument, which is the kind of object we're expecting to receive from the other side. If we get + back something else an exception is thrown. -Once ``sendAndReceive`` is called, the call method will be suspended into a continuation. When it gets back we'll do a log -message. The buyer is supposed to send us a transaction with all the right inputs/outputs/commands in return, with their -cash put into the transaction and their signature on it authorising the movement of the cash. +Once ``sendAndReceive`` is called, the call method will be suspended into a continuation and saved to persistent +storage. If the node crashes or is restarted, the protocol will effectively continue as if nothing had happened. Your +code may remain blocked inside such a call for seconds, minutes, hours or even days in the case of a protocol that +needs human interaction! .. note:: There are a couple of rules you need to bear in mind when writing a class that will be used as a continuation. The first is that anything on the stack when the function is suspended will be stored into the heap and kept alive by @@ -331,31 +302,51 @@ cash put into the transaction and their signature on it authorising the movement The second is that as well as being kept on the heap, objects reachable from the stack will be serialised. The state of the function call may be resurrected much later! Kryo doesn't require objects be marked as serialisable, but even so, doing things like creating threads from inside these calls would be a bad idea. They should only contain business - logic. + logic and only do I/O via the methods exposed by the protocol framework. + + It's OK to keep references around to many large internal node services though: these will be serialised using a + special token that's recognised by the platform, and wired up to the right instance when the continuation is + loaded off disk again. + +The buyer is supposed to send us a transaction with all the right inputs/outputs/commands in response to the opening +message, with their cash put into the transaction and their signature on it authorising the movement of the cash. You get back a simple wrapper class, ``UntrustworthyData``, which is just a marker class that reminds us that the data came from a potentially malicious external source and may have been tampered with or be unexpected in -other ways. It doesn't add any functionality, but acts as a reminder to "scrub" the data before use. Here, our scrubbing -simply involves checking the signatures on it. Then we go ahead and check all the dependencies of this partial -transaction for validity. Here's the code to do that: +other ways. It doesn't add any functionality, but acts as a reminder to "scrub" the data before use. + +Our "scrubbing" has three parts: + +1. Check that the expected signatures are present and correct. At this point we expect our own signature to be missing, + because of course we didn't sign it yet, and also the signature of the notary because that must always come last. +2. We resolve the transaction, which we will cover below. +3. We verify that the transaction is paying us the demanded price. + +Subprotocols +------------ + +Protocols can be composed via nesting. Invoking a sub-protocol looks similar to an ordinary function call: .. container:: codeset .. sourcecode:: kotlin @Suspendable - private fun checkDependencies(stx: SignedTransaction) { - // Download and check all the transactions that this transaction depends on, but do not check this - // transaction itself. - val dependencyTxIDs = stx.tx.inputs.map { it.txhash }.toSet() - subProtocol(ResolveTransactionsProtocol(dependencyTxIDs, otherSide)) + private fun getNotarySignature(stx: SignedTransaction): DigitalSignature.LegallyIdentifiable { + progressTracker.currentStep = NOTARY + return subProtocol(NotaryProtocol.Client(stx)) } -This is simple enough: we mark the method as ``@Suspendable`` because we're going to invoke a sub-protocol, extract the -IDs of the transactions the proposed transaction depends on, and then uses a protocol provided by the system to download -and check them all. This protocol does a breadth-first search over the dependency graph, bottoming out at issuance -transactions that don't have any inputs themselves. Once the node has audited the transaction history, all the dependencies -are committed to the node's local database so they won't be checked again next time. +In this code snippet we are using the ``NotaryProtocol.Client`` to request notarisation of the transaction. +We simply create the protocol object via its constructor, and then pass it to the ``subProtocol`` method which +returns the result of the protocol's execution directly. Behind the scenes all this is doing is wiring up progress +tracking (discussed more below) and then running the objects ``call`` method. Because this little helper method can +be on the stack when network IO takes place, we mark it as ``@Suspendable``. + +Going back to the previous code snippet, we use a subprotocol called ``ResolveTransactionsProtocol``. This is +responsible for downloading and checking all the dependencies of a transaction, which in Corda are always retrievable +from the party that sent you a transaction that uses them. This protocol returns a list of ``LedgerTransaction`` +objects, but we don't need them here so we just ignore the return value. .. note:: Transaction dependency resolution assumes that the peer you got the transaction from has all of the dependencies itself. It must do, otherwise it could not have convinced itself that the dependencies were themselves @@ -375,24 +366,27 @@ Here's the rest of the code: open fun signWithOurKey(partialTX: SignedTransaction) = myKeyPair.signWithECDSA(partialTX.txBits) @Suspendable - open fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey, - tsaSig: DigitalSignature.LegallyIdentifiable): SignedTransaction { - val fullySigned = partialTX + tsaSig + ourSignature - + private fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey, + notarySignature: DigitalSignature.LegallyIdentifiable): SignedTransaction { + val fullySigned = partialTX + ourSignature + notarySignature logger.trace { "Built finished transaction, sending back to secondary!" } - - send(TRADE_TOPIC, otherSide, buyerSessionID, SignaturesFromSeller(tsaSig, ourSignature)) + send(otherSide, buyerSessionID, SignaturesFromSeller(ourSignature, notarySignature)) return fullySigned } -It's should be all pretty straightforward: here, ``txBits`` is the raw byte array representing the transaction. +It's all pretty straightforward from now on. Here ``txBits`` is the raw byte array representing the serialised +transaction, and we just use our private key to calculate a signature over it. As a reminder, in Corda signatures do +not cover other signatures: just the core of the transaction data. -In ``sendSignatures``, we take the two signatures we calculated, then add them to the partial transaction we were sent. -We provide an overload for the + operator so signatures can be added to a SignedTransaction easily. Finally, we wrap the +In ``sendSignatures``, we take the two signatures we obtained and add them to the partial transaction we were sent. +There is an overload for the + operator so signatures can be added to a SignedTransaction easily. Finally, we wrap the two signatures in a simple wrapper message class and send it back. The send won't block waiting for an acknowledgement, but the underlying message queue software will retry delivery if the other side has gone away temporarily. -.. warning:: This code is **not secure**. Other than not checking for all possible invalid constructions, if the +You can also see that every protocol instance has a logger (using the SLF4J API) which you can use to log progress +messages. + +.. warning:: This sample code is **not secure**. Other than not checking for all possible invalid constructions, if the seller stops before sending the finalised transaction to the buyer, the seller is left with a valid transaction but the buyer isn't, so they can't spend the asset they just purchased! This sort of thing will be fixed in a future version of the code. @@ -411,24 +405,25 @@ OK, let's do the same for the buyer side: val tradeRequest = receiveAndValidateTradeRequest() val (ptx, cashSigningPubKeys) = assembleSharedTX(tradeRequest) val stx = signWithOurKeys(cashSigningPubKeys, ptx) + val signatures = swapSignaturesWithSeller(stx, tradeRequest.sessionID) - logger.trace { "Got signatures from seller, verifying ... "} - val fullySigned = stx + signatures.timestampAuthoritySig + signatures.sellerSig - fullySigned.verify() + logger.trace { "Got signatures from seller, verifying ... " } - logger.trace { "Fully signed transaction was valid. Trade complete! :-)" } + val fullySigned = stx + signatures.sellerSig + signatures.notarySig + fullySigned.verifySignatures() + + logger.trace { "Signatures received are valid. Trade complete! :-)" } return fullySigned } @Suspendable - open fun receiveAndValidateTradeRequest(): SellerTradeInfo { + private fun receiveAndValidateTradeRequest(): SellerTradeInfo { // Wait for a trade request to come in on our pre-provided session ID. - val maybeTradeRequest = receive(TRADE_TOPIC, sessionID) - + val maybeTradeRequest = receive(sessionID) maybeTradeRequest.validate { // What is the seller trying to sell us? - val asset = it.assetForSale.state + val asset = it.assetForSale.state.data val assetTypeName = asset.javaClass.name logger.trace { "Got trade request for a $assetTypeName: ${it.assetForSale}" } @@ -448,15 +443,16 @@ OK, let's do the same for the buyer side: } @Suspendable - open fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller { + private fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller { + progressTracker.currentStep = SWAPPING_SIGNATURES logger.trace { "Sending partially signed transaction to seller" } // 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, SignaturesFromSeller::class.java).validate { it } + return sendAndReceive(otherSide, theirSessionID, sessionID, stx).validate { it } } - open fun signWithOurKeys(cashSigningPubKeys: List, ptx: TransactionBuilder): SignedTransaction { + private fun signWithOurKeys(cashSigningPubKeys: List, ptx: TransactionBuilder): SignedTransaction { // Now sign the transaction with whatever keys we need to move the cash. for (k in cashSigningPubKeys) { val priv = serviceHub.keyManagementService.toPrivate(k) @@ -466,50 +462,45 @@ OK, let's do the same for the buyer side: return ptx.toSignedTransaction(checkSufficientSignatures = false) } - open fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair> { - val ptx = TransactionBuilder() + private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair> { + val ptx = TransactionType.General.Builder(notary) // Add input and output states for the movement of cash, by using the Cash contract to generate the states. val wallet = serviceHub.walletService.currentWallet val cashStates = wallet.statesOfType() val cashSigningPubKeys = Cash().generateSpend(ptx, tradeRequest.price, tradeRequest.sellerOwnerKey, cashStates) // Add inputs/outputs/a command for the movement of the asset. - ptx.addInputState(tradeRequest.assetForSale.ref) + ptx.addInputState(tradeRequest.assetForSale) // Just pick some new public key for now. This won't be linked with our identity in any way, which is what // we want for privacy reasons: the key is here ONLY to manage and control ownership, it is not intended to // reveal who the owner actually is. The key management service is expected to derive a unique key from some // initial seed in order to provide privacy protection. val freshKey = serviceHub.keyManagementService.freshKey() - val (command, state) = tradeRequest.assetForSale.state.withNewOwner(freshKey.public) - ptx.addOutputState(state) - ptx.addCommand(command, tradeRequest.assetForSale.state.owner) + val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public) + ptx.addOutputState(state, tradeRequest.assetForSale.state.notary) + ptx.addCommand(command, tradeRequest.assetForSale.state.data.owner) // 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(Instant.now(), timestampingAuthority, 30.seconds) + val currentTime = serviceHub.clock.instant() + ptx.setTime(currentTime, 30.seconds) return Pair(ptx, cashSigningPubKeys) } -This code is longer but still fairly straightforward. Here are some things to pay attention to: +This code is longer but no more complicated. Here are some things to pay attention to: 1. We do some sanity checking on the received message to ensure we're being offered what we expected to be offered. -2. We create a cash spend in the normal way, by using ``Cash().generateSpend``. See the contracts tutorial if this isn't - clear. +2. We create a cash spend in the normal way, by using ``Cash().generateSpend``. See the contracts tutorial if this + part isn't clear. 3. We access the *service hub* when we need it to access things that are transient and may change or be recreated - whilst a protocol is suspended, things like the wallet or the timestamping service. Remember that a protocol may - be suspended when it waits to receive a message across node or computer restarts, so objects representing a service - or data which may frequently change should be accessed 'just in time'. + whilst a protocol is suspended, things like the wallet or the network map. 4. Finally, we send the unfinished, invalid transaction to the seller so they can sign it. They are expected to send back to us a ``SignaturesFromSeller``, which once we verify it, should be the final outcome of the trade. As you can see, the protocol logic is straightforward and does not contain any callbacks or network glue code, despite the fact that it takes minimal resources and can survive node restarts. -.. warning:: When accessing things via the ``serviceHub`` field, avoid the temptation to stuff a reference into a local variable. - If you do this then next time your protocol waits to receive an object, the system will try and serialise all your - local variables and end up trying to serialise, e.g. the timestamping service, which doesn't make any conceptual - sense. The ``serviceHub`` field is defined by the ``ProtocolStateMachine`` superclass and is marked transient so - this problem doesn't occur. It's also restored for you when a protocol state machine is restored after a node - restart. +.. warning:: In the current version of the platform, exceptions thrown during protocol execution are not propagated + back to the sender. A thorough error handling and exceptions framework will be in a future version of the platform. Progress tracking ----------------- @@ -662,3 +653,36 @@ directly to the ``a.services.recordTransaction`` method (note that this method d valid). And that's it: you can explore the documentation for the `MockNode API `_ here. + +Versioning +---------- + +Fibers involve persisting object-serialised stack frames to disk. Although we may do some R&D into in-place upgrades +in future, for now the upgrade process for protocols is simple: you duplicate the code and rename it so it has a +new set of class names. Old versions of the protocol can then drain out of the system whilst new versions are +initiated. When enough time has passed that no old versions are still waiting for anything to happen, the previous +copy of the code can be deleted. + +Whilst kind of ugly, this is a very simple approach that should suffice for now. + +.. warning:: Protocols are not meant to live for months or years, and by implication they are not meant to implement entire deal + lifecycles. For instance, implementing the entire life cycle of an interest rate swap as a single protocol - whilst + technically possible - would not be a good idea. The platform provides a job scheduler tool that can invoke + protocols for this reason (see ":doc:`event-scheduling`") + +Future features +--------------- + +The protocol framework is a key part of the platform and will be extended in major ways in future. Here are some of +the features we have planned: + +* Automatic session ID management +* Identity based addressing +* Exposing progress trackers to local (inside the firewall) clients using message queues and/or WebSockets +* Exception propagation and management, with a "protocol hospital" tool to manually provide solutions to unavoidable + problems (e.g. the other side doesn't know the trade) +* Being able to interact with internal apps and tools via HTTP and similar +* Being able to interact with people, either via some sort of external ticketing system, or email, or a custom UI. + For example to implement human transaction authorisations. +* A standard library of protocols that can be easily sub-classed by local developers in order to integrate internal + reporting logic, or anything else that might be required as part of a communications lifecycle. diff --git a/docs/build/html/_sources/release-process.txt b/docs/build/html/_sources/release-process.txt index 5cdf4201c9..2fcc8f1e58 100644 --- a/docs/build/html/_sources/release-process.txt +++ b/docs/build/html/_sources/release-process.txt @@ -34,11 +34,11 @@ Steps to cut a 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. 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. +7. Remove the "is master" warning from the docsite index page on this branch only. +8. Tag the branch with a tag like `release-M0.0` +9. Push the branch and the tag to git. +10. Write up a short announcement containing the summary of new features, changes, and API breaks. Send it to the r3dlg-awg mailing list. +11. 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/build/html/_sources/running-the-demos.txt b/docs/build/html/_sources/running-the-demos.txt index 5c51afc789..1544f58e13 100644 --- a/docs/build/html/_sources/running-the-demos.txt +++ b/docs/build/html/_sources/running-the-demos.txt @@ -13,9 +13,6 @@ so far. We have: The demos create node data directories in the root of the project. If something goes wrong with them, blow away the directories and try again. -.. note:: Corda is developed on MacOS and works best on UNIX systems. Both demos are easily run on Windows but - you won't get the nice coloured output. - Trader demo ----------- @@ -106,7 +103,7 @@ To install the web demo please follow these steps; 1. Install Node: https://nodejs.org/en/download/ and ensure the npm executable is on your classpath 2. Open a terminal -3. Run `npm install -g bower` or `sudo npm install -g bower` if on a *nix system. +3. Run `npm install -g bower` or `sudo npm install -g bower` if on a Unix system. 4. In the terminal navigate to `/src/main/resources/com/r3corda/demos/irswebdemo` 5. Run `bower install` diff --git a/docs/build/html/_sources/transaction-data-types.txt b/docs/build/html/_sources/transaction-data-types.txt index b59e3a7792..9b179df7c5 100644 --- a/docs/build/html/_sources/transaction-data-types.txt +++ b/docs/build/html/_sources/transaction-data-types.txt @@ -1,63 +1,85 @@ Data types ========== -There is a large library of data types used in Corda transactions and contract state objects. +Corda provides a large standard library of data types used in financial transactions and contract state objects. +These provide a common language for states and contracts. Amount ------ -The ``Amount`` class is used to represent an amount of some fungible asset. It is a generic class which wraps around -a type used to define the underlying product, generally represented by an ``Issued`` instance, or this can be a more -complex type such as an obligation contract issuance definition (which in turn contains a token definition for whatever -the obligation is to be settled in). +The `Amount `_ class is used to represent an amount of some +fungible asset. It is a generic class which wraps around a type used to define the underlying product, called +the *token*. For instance it can be the standard JDK type ``Currency``, or an ``Issued`` instance, or this can be +a more complex type such as an obligation contract issuance definition (which in turn contains a token definition +for whatever the obligation is to be settled in). .. note:: Fungible is used here to mean that instances of an asset is interchangeable for any other identical instance, and that they can be split/merged. For example a £5 note can reasonably be exchanged for any other £5 note, and a £10 note can be exchanged for two £5 notes, or vice-versa. -Where a contract refers directly to an amount of something, ``Amount`` should wrap ``Issued``, which in -turn can refer to a ``Currency`` (GBP, USD, CHF, etc.), or any other class. Future work in this area will include -introducing classes to represent non-currency things (such as commodities) that Issued can wrap. For more -complex amounts, ``Amount`` can wrap other types, for example to represent a number of Obligation contracts to be -delivered (themselves referring to a currency), an ``Amount`` such as the following would used: +Here are some examples: .. container:: codeset .. sourcecode:: kotlin + // A quantity of some specific currency like pounds, euros, dollars etc. + Amount + // A quantity of currency that is issued by a specific issuer, for instance central bank vs other bank dollars + Amount> + // A quantity of obligations to deliver currency of any issuer. Amount> +``Amount`` represents quantities as integers. For currencies the quantity represents pennies, cents or whatever +else the smallest integer amount for that currency is. You cannot use ``Amount`` to represent negative quantities +or fractional quantities: if you wish to do this then you must use a different type e.g. ``BigDecimal``. ``Amount`` +defines methods to do addition and subtraction and these methods verify that the tokens on both sides of the operator +are equal (these are operator overloads in Kotlin and can be used as regular methods from Java). There are also +methods to do multiplication and division by integer amounts. + 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 ``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 details of a specific deal or asset (see :doc:`data-model` for further detail). In relational database terms +a state is like a row in a database. A reference to a state in the ledger (whether it has been consumed or not) +is represented with a ``StateRef`` object. If the state ref has been looked up from storage, you will have a +``StateAndRef`` which is simply a ``StateRef`` plus the data. -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`). +The ``ContractState`` type is an interface that all states must implement. A ``TransactionState`` is a simple +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: +A number of interfaces then extend ``ContractState``, representing standardised functionality for common kinds +of state: ``OwnableState`` - A state which has an owner (represented as a ``PublicKey``, discussed later). Exposes the owner and a function for - replacing the owner. + A state which has an owner (represented as a ``PublicKey``, discussed later). Exposes the owner and a function + for replacing the owner e.g. when an asset is sold. ``LinearState`` - A state which links back to its previous state, creating a thread of states over time. Intended to simplify tracking - state versions. + A state which links back to its previous state, creating a thread of states over time. A linear state is + useful when modelling an indivisible/non-fungible thing like a specific deal, or an asset that can't be + split (like a rare piece of art). ``DealState`` - A state representing an agreement between two or more parties. Intended to simplify implementing generic protocols - that manipulate many agreement types. + A LinearState representing an agreement between two or more parties. Intended to simplify implementing generic + protocols that manipulate many agreement types. ``FixableDealState`` A deal state, with further functions exposed to support fixing of interest rates. -Things (such as attachments) which are identified by their hash should implement the ``NamedByHash`` interface, -which standardises how the ID is extracted. +NamedByHash and UniqueIdentifier +-------------------------------- + +Things which are identified by their hash, like transactions and attachments, should implement the ``NamedByHash`` +interface which standardises how the ID is extracted. Note that a hash is *not* a globally unique identifier: it +is always a derivative summary of the contents of the underlying data. Sometimes this isn't what you want: +two deals that have exactly the same parameters and which are made simultaneously but which are logically different +can't be identified by hash because their contents would be identical. Instead you would use ``UniqueIdentifier``. +This is a combination of a (Java) ``UUID`` representing a globally unique 128 bit random number, and an arbitrary +string which can be paired with it. For instance the string may represent an existing "weak" (not guaranteed unique) +identifier for convenience purposes. FungibleAssets and Cash ----------------------- @@ -77,6 +99,9 @@ in place of the attachments themselves (see also :doc:`data-model`). Once signed resolving the attachment references to the attachments. Commands with valid signatures are encapsulated in the ``AuthenticatedObject`` type. +.. note:: A ``LedgerTransaction`` has not necessarily had its contracts be run, and thus could be contract-invalid + (but not signature-invalid). You can use the ``verify`` method as shown below to run the contracts. + When constructing a new transaction from scratch, you use ``TransactionBuilder``, which is a mutable transaction that can be signed once modification of the internals is complete. It is typical for contract classes to expose helper methods that can contribute to a ``TransactionBuilder``. @@ -105,12 +130,20 @@ write your tests using the :doc:`domain specific language for writing tests `_. diff --git a/docs/build/html/_sources/tutorial-contract-clauses.txt b/docs/build/html/_sources/tutorial-contract-clauses.txt index eb1ee343c0..325fcc437c 100644 --- a/docs/build/html/_sources/tutorial-contract-clauses.txt +++ b/docs/build/html/_sources/tutorial-contract-clauses.txt @@ -10,14 +10,18 @@ Writing a contract using clauses This tutorial will take you through restructuring the commercial paper contract to use clauses. You should have already completed ":doc:`tutorial-contract`". -Clauses are essentially micro-contracts which contain independent verification logic, and are composed together to form -a contract. With appropriate design, they can be made to be reusable, for example issuing contract state objects is -generally the same for all fungible contracts, so a single issuance clause can be shared. This cuts down on scope for -error, and improves consistency of behaviour. +Clauses are essentially micro-contracts which contain independent verification logic, and can be logically composed +together to form a contract. Clauses are designed to enable re-use of common logic, for example issuing state objects +is generally the same for all fungible contracts, so a common issuance clause can be inherited for each contract's +issue clause. This cuts down on scope for error, and improves consistency of behaviour. By splitting verification logic +into smaller chunks, they can also be readily tested in isolation. -Clauses can be composed of subclauses, either to combine clauses in different ways, or to apply specialised clauses. -In the case of commercial paper, we have a ``Group`` outermost clause, which will contain the ``Issue``, ``Move`` and -``Redeem`` clauses. The result is a contract that looks something like this: +Clauses can be composed of subclauses, for example the ``AllClause`` or ``AnyClause`` clauses take list of clauses +that they delegate to. Clauses can also change the scope of states and commands being verified, for example grouping +together fungible state objects and running a clause against each distinct group. + +The commercial paper contract has a ``Group`` outermost clause, which contains the ``Issue``, ``Move`` and ``Redeem`` +clauses. The result is a contract that looks something like this: 1. Group input and output states together, and then apply the following clauses on each group: a. If an ``Issue`` command is present, run appropriate tests and end processing this group. @@ -27,11 +31,12 @@ In the case of commercial paper, we have a ``Group`` outermost clause, which wil Commercial paper class ---------------------- -To use the clause verification logic, the contract needs to call the ``verifyClauses()`` function, passing in the transaction, -a list of clauses to verify, and a collection of commands the clauses are expected to handle all of. This list of -commands is important because ``verifyClauses()`` checks that none of the commands are left unprocessed at the end, and -raises an error if they are. The following examples are trimmed to the modified class definition and added elements, for -brevity: +To use the clause verification logic, the contract needs to call the ``verifyClause`` function, passing in the +transaction, a clause to verify, and a collection of commands the clauses are expected to handle all of. This list of +commands is important because ``verifyClause`` checks that none of the commands are left unprocessed at the end, and +raises an error if they are. The top level clause would normally be a composite clause (such as ``AnyComposition``, +``AllComposition``, etc.) which contains further clauses. The following examples are trimmed to the modified class +definition and added elements, for brevity: .. container:: codeset @@ -40,10 +45,7 @@ brevity: class CommercialPaper : Contract { override val legalContractReference: SecureHash = SecureHash.sha256("https://en.wikipedia.org/wiki/Commercial_paper") - private fun extractCommands(tx: TransactionForContract): List> - = tx.commands.select() - - override fun verify(tx: TransactionForContract) = verifyClauses(tx, listOf(Clauses.Group()), extractCommands(tx)) + override fun verify(tx: TransactionForContract) = verifyClause(tx, Clauses.Group(), tx.commands.select()) .. sourcecode:: java @@ -53,53 +55,40 @@ brevity: return SecureHash.Companion.sha256("https://en.wikipedia.org/wiki/Commercial_paper"); } - @Override - public Collection> extractCommands(@NotNull TransactionForContract tx) { - return tx.getCommands() - .stream() - .filter((AuthenticatedObject command) -> { return command.getValue() instanceof Commands; }) - .collect(Collectors.toList()); - } - @Override public void verify(@NotNull TransactionForContract tx) throws IllegalArgumentException { - ClauseVerifier.verifyClauses(tx, Collections.singletonList(new Clause.Group()), extractCommands(tx)); + ClauseVerifier.verifyClause(tx, new Clauses.Group(), extractCommands(tx)); } Clauses ------- We'll tackle the inner clauses that contain the bulk of the verification logic, first, and the clause which handles -grouping of input/output states later. The inner clauses need to implement the ``GroupClause`` interface, which defines -the verify() function, and properties (``ifMatched``, ``ifNotMatched`` and ``requiredCommands``) defining how the clause -is processed. These properties specify the command(s) which must be present in order for the clause to be matched, -and what to do after processing the clause depending on whether it was matched or not. +grouping of input/output states later. The clauses must implement the ``Clause`` interface, which defines +the ``verify`` function, and the ``requiredCommands`` property used to determine the conditions under which a clause +is triggered. Normally clauses would extend ``ConcreteClause`` which provides defaults suitable for a clause which +verifies transactions, rather than delegating to other clauses. -The ``verify()`` functions defined in the ``SingleClause`` and ``GroupClause`` interfaces is similar to the conventional -``Contract`` verification function, although it adds new parameters and returns the set of commands which it has processed. -Normally this returned set is identical to the commands matched in order to trigger the clause, however in some cases the -clause may process optional commands which it needs to report that it has handled, or may by designed to only process -the first (or otherwise) matched command. +The ``verify`` function defined in the ``Clause`` interface is similar to the conventional ``Contract`` verification +function, although it adds new parameters and returns the set of commands which it has processed. Normally this returned +set is identical to the ``requiredCommands`` used to trigger the clause, however in some cases the clause may process +further optional commands which it needs to report that it has handled. -The Move clause for the commercial paper contract is relatively simple, so lets start there: +The ``Move`` clause for the commercial paper contract is relatively simple, so we will start there: .. container:: codeset .. sourcecode:: kotlin - class Move: GroupClause> { - override val ifNotMatched: MatchBehaviour - get() = MatchBehaviour.CONTINUE - override val ifMatched: MatchBehaviour - get() = MatchBehaviour.END + class Move: ConcreteClause>() { override val requiredCommands: Set> get() = setOf(Commands.Move::class.java) override fun verify(tx: TransactionForContract, inputs: List, outputs: List, - commands: Collection>, - token: Issued): Set { + commands: List>, + groupingKey: Issued?): Set { val command = commands.requireSingleCommand() val input = inputs.single() requireThat { @@ -114,140 +103,79 @@ The Move clause for the commercial paper contract is relatively simple, so lets .. sourcecode:: java - public class Move implements GroupClause { - @Override - public MatchBehaviour getIfNotMatched() { - return MatchBehaviour.CONTINUE; - } - - @Override - public MatchBehaviour getIfMatched() { - return MatchBehaviour.END; - } - + class Move extends ConcreteClause { + @NotNull @Override public Set> getRequiredCommands() { return Collections.singleton(Commands.Move.class); } + @NotNull @Override - public Set verify(@NotNull TransactionForContract tx, + public Set verify(@NotNull TransactionForContract tx, @NotNull List inputs, @NotNull List outputs, - @NotNull Collection> commands, - @NotNull State token) { - AuthenticatedObject cmd = requireSingleCommand(tx.getCommands(), JavaCommercialPaper.Commands.Move.class); + @NotNull List> commands, + @NotNull State groupingKey) { + AuthenticatedObject cmd = requireSingleCommand(tx.getCommands(), Commands.Move.class); // There should be only a single input due to aggregation above State input = single(inputs); - requireThat(require -> { - require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner())); - require.by("the state is propagated", outputs.size() == 1); - return Unit.INSTANCE; - }); + if (!cmd.getSigners().contains(input.getOwner())) + throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP"); + + // Check the output CP state is the same as the input state, ignoring the owner field. + if (outputs.size() != 1) { + throw new IllegalStateException("the state is propagated"); + } // Don't need to check anything else, as if outputs.size == 1 then the output is equal to // the input ignoring the owner field due to the grouping. return Collections.singleton(cmd.getValue()); } } -The post-processing ``MatchBehaviour`` options are: - * CONTINUE - * END - * ERROR - -In this case we process commands against each group, until the first matching clause is found, so we ``END`` on a match -and ``CONTINUE`` otherwise. ``ERROR`` can be used as a part of a clause which must always/never be matched. By default -clauses are always matched (``requiredCommands`` is an empty set), execution continues after a clause is matched, and an -error is raised if a clause is not matched. - Group Clause ------------ We need to wrap the move clause (as well as the issue and redeem clauses - see the relevant contract code for their -full specifications) in an outer clause. For this we extend the standard ``GroupClauseVerifier`` and specify how to -group input/output states, as well as the clauses to run on each group. +full specifications) in an outer clause that understands how to group contract states and objects. For this we extend +the standard ``GroupClauseVerifier`` and specify how to group input/output states, as well as the top-level to run on +each group. As with the top level clause on a contract, this is normally a composite clause that delegates to subclauses. .. container:: codeset .. sourcecode:: kotlin - class Group : GroupClauseVerifier>() { - override val ifNotMatched: MatchBehaviour - get() = MatchBehaviour.ERROR - override val ifMatched: MatchBehaviour - get() = MatchBehaviour.END - override val clauses: List>> - get() = listOf( - Clause.Redeem(), - Clause.Move(), - Clause.Issue() - ) - - override fun extractGroups(tx: TransactionForContract): List>> + class Group : GroupClauseVerifier>( + AnyComposition( + Redeem(), + Move(), + Issue())) { + override fun groupStates(tx: TransactionForContract): List>> = tx.groupStates> { it.token } } .. sourcecode:: java - public class Group extends GroupClauseVerifier { - @Override - public MatchBehaviour getIfMatched() { - return MatchBehaviour.END; + class Group extends GroupClauseVerifier { + public Group() { + super(new AnyComposition<>( + new Clauses.Redeem(), + new Clauses.Move(), + new Clauses.Issue() + )); } + @NotNull @Override - public MatchBehaviour getIfNotMatched() { - return MatchBehaviour.ERROR; - } - - @Override - public List> getClauses() { - final List> clauses = new ArrayList<>(); - - clauses.add(new Clause.Redeem()); - clauses.add(new Clause.Move()); - clauses.add(new Clause.Issue()); - - return clauses; - } - - @Override - public List> extractGroups(@NotNull TransactionForContract tx) { + public List> groupStates(@NotNull TransactionForContract tx) { return tx.groupStates(State.class, State::withoutOwner); } } -We then pass this clause into the outer ``ClauseVerifier`` contract by returning it from the ``clauses`` property. We -also implement the ``extractCommands()`` function, which filters commands on the transaction down to the set the -contained clauses must handle (any unmatched commands at the end of clause verification results in an exception to be -thrown). - -.. container:: codeset - - .. sourcecode:: kotlin - - override val clauses: List - get() = listOf(Clauses.Group()) - - override fun extractCommands(tx: TransactionForContract): List> - = tx.commands.select() - - .. sourcecode:: java - - @Override - public List getClauses() { - return Collections.singletonList(new Clause.Group()); - } - - @Override - public Collection> extractCommands(@NotNull TransactionForContract tx) { - return tx.getCommands() - .stream() - .filter((AuthenticatedObject command) -> { return command.getValue() instanceof Commands; }) - .collect(Collectors.toList()); - } +For the ``CommercialPaper`` contract, this is the top level clause for the contract, and is passed directly into +``verifyClause`` (see the example code at the top of this tutorial). Summary ------- @@ -255,4 +183,12 @@ Summary In summary the top level contract ``CommercialPaper`` specifies a single grouping clause of type ``CommercialPaper.Clauses.Group`` which in turn specifies ``GroupClause`` implementations for each type of command (``Redeem``, ``Move`` and ``Issue``). This reflects the flow of verification: In order to verify a ``CommercialPaper`` -we first group states, check which commands are specified, and run command-specific verification logic accordingly. \ No newline at end of file +we first group states, check which commands are specified, and run command-specific verification logic accordingly. + +Debugging +--------- + +Debugging clauses which have been composed together can be complicated due to the difficulty in knowing which clauses +have been matched, whether specific clauses failed to match or passed verification, etc. There is "trace" level +logging code in the clause verifier which evaluates which clauses will be matched and logs them, before actually +performing the validation. To enable this, ensure trace level logging is enabled on the ``Clause`` interface. diff --git a/docs/build/html/_sources/tutorial-contract.txt b/docs/build/html/_sources/tutorial-contract.txt index f149a8a433..c3b1b4ca75 100644 --- a/docs/build/html/_sources/tutorial-contract.txt +++ b/docs/build/html/_sources/tutorial-contract.txt @@ -9,18 +9,26 @@ Writing a contract This tutorial will take you through how the commercial paper contract works. This uses a simple contract structure of everything being in one contract class, while most actual contracts in Corda are broken into clauses (which we'll -discuss in the next tutorial). You can see the full Kotlin version of this contract in the code as ``CommercialPaperLegacy``. +discuss in the next tutorial). Clauses help reduce tedious boilerplate, but it's worth understanding how a +contract is built without them before starting. -The code in this tutorial is available in both Kotlin and Java. You can quickly switch between them to get a feeling -for how Kotlin syntax works. +You can see the full Kotlin version of this contract in the code as ``CommercialPaperLegacy``. The code in this +tutorial is available in both Kotlin and Java. You can quickly switch between them to get a feeling for how +Kotlin syntax works. + +Where to put your code +---------------------- + +A CorDapp is a collection of contracts, state definitions, protocols and other ways to extend the server. To create +one you would just create a Java-style project as normal, with your choice of build system (Maven, Gradle, etc). +Then add a dependency on ``com.r3corda:core:0.X`` where X is the milestone number you are depending on. The core +module defines the base classes used in this tutorial. Starting the commercial paper class ----------------------------------- A smart contract is a class that implements the ``Contract`` interface. This can be either implemented directly, or -via an abstract contract such as ``ClauseVerifier``. For now, contracts have to be a part of the main codebase, as -dynamic loading of contract code is not yet implemented. Therefore, we start by creating a file named either -``CommercialPaper.kt`` or ``CommercialPaper.java`` in the ``contracts/src/main`` directory with the following contents: +by subclassing an abstract contract such as ``OnLedgerAsset``. .. container:: codeset @@ -52,13 +60,11 @@ Every contract must have at least a ``getLegalContractReference()`` and a ``veri a getter without a setter as an immutable property (val). The *legal contract reference* is supposed to be a hash of a document that describes the legal contract and may take precedence over the code, in case of a dispute. +.. note:: The way legal contract prose is bound to a smart contract implementation will change in future. + The verify method returns nothing. This is intentional: the function either completes correctly, or throws an exception, in which case the transaction is rejected. -We also need to define a constant hash that would, in a real system, be the hash of the program bytecode. For now -we just set it to a dummy value as dynamic loading and sandboxing of bytecode is not implemented. This constant -isn't shown in the code snippet but is called ``CP_PROGRAM_ID``. - So far, so simple. Now we need to define the commercial paper *state*, which represents the fact of ownership of a piece of issued paper. @@ -72,101 +78,117 @@ A state is a class that stores data that is checked by the contract. .. sourcecode:: kotlin data class State( - val issuance: InstitutionReference, - val owner: PublicKey, - val faceValue: Amount, - val maturityDate: Instant - ) : ContractState { - override val programRef = CP_PROGRAM_ID + val issuance: PartyAndReference, + override val owner: PublicKey, + val faceValue: Amount>, + val maturityDate: Instant + ) : OwnableState { + override val contract = CommercialPaper() + override val participants = listOf(owner) - fun withoutOwner() = copy(owner = NullPublicKey) + fun withoutOwner() = copy(owner = NullPublicKey) + override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner)) } .. sourcecode:: java - public static class State implements ContractState, SerializeableWithKryo { - private InstitutionReference issuance; - private PublicKey owner; - private Amount faceValue; - private Instant maturityDate; + public static class State implements OwnableState { + private PartyAndReference issuance; + private PublicKey owner; + private Amount> faceValue; + private Instant maturityDate; - public State() {} // For serialization + public State() { + } // For serialization - public State(InstitutionReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) { - this.issuance = issuance; - this.owner = owner; - this.faceValue = faceValue; - this.maturityDate = maturityDate; - } + public State(PartyAndReference issuance, PublicKey owner, Amount> faceValue, + Instant maturityDate) { + this.issuance = issuance; + this.owner = owner; + this.faceValue = faceValue; + this.maturityDate = maturityDate; + } - public InstitutionReference getIssuance() { - return issuance; - } + public State copy() { + return new State(this.issuance, this.owner, this.faceValue, this.maturityDate); + } - public PublicKey getOwner() { - return owner; - } + @NotNull + @Override + public Pair withNewOwner(@NotNull PublicKey newOwner) { + return new Pair<>(new Commands.Move(), new State(this.issuance, newOwner, this.faceValue, this.maturityDate)); + } - public Amount getFaceValue() { - return faceValue; - } + public PartyAndReference getIssuance() { + return issuance; + } - public Instant getMaturityDate() { - return maturityDate; - } + public PublicKey getOwner() { + return owner; + } - @NotNull - @Override - public SecureHash getProgramRef() { - return SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)"); - } + public Amount> getFaceValue() { + return faceValue; + } - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + public Instant getMaturityDate() { + return maturityDate; + } - State state = (State) o; + @NotNull + @Override + public Contract getContract() { + return new JavaCommercialPaper(); + } - if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false; - if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false; - if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false; - return !(maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null); + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; - } + State state = (State) o; - @Override - public int hashCode() { - int result = issuance != null ? issuance.hashCode() : 0; - result = 31 * result + (owner != null ? owner.hashCode() : 0); - result = 31 * result + (faceValue != null ? faceValue.hashCode() : 0); - result = 31 * result + (maturityDate != null ? maturityDate.hashCode() : 0); - return result; - } + if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false; + if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false; + if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false; + return !(maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null); + } - public State withoutOwner() { - return new State(issuance, NullPublicKey.INSTANCE, faceValue, maturityDate); - } + @Override + public int hashCode() { + int result = issuance != null ? issuance.hashCode() : 0; + result = 31 * result + (owner != null ? owner.hashCode() : 0); + result = 31 * result + (faceValue != null ? faceValue.hashCode() : 0); + result = 31 * result + (maturityDate != null ? maturityDate.hashCode() : 0); + return result; + } + + @NotNull + @Override + public List getParticipants() { + return ImmutableList.of(this.owner); + } } -We define a class that implements the ``ContractState`` and ``SerializableWithKryo`` interfaces. The -latter is an artifact of how the prototype implements serialization and can be ignored for now: it wouldn't work -like this in any final product. -The ``ContractState`` interface requires us to provide a ``getProgramRef`` method that is supposed to return a hash of -the bytecode of the contract itself. For now this is a dummy value and isn't used: later on, this mechanism will change. -Beyond that it's a freeform object into which we can put anything which can be serialized. +We define a class that implements the ``ContractState`` interface. + +The ``ContractState`` interface requires us to provide a ``getContract`` method that returns an instance of the +contract class itself. In future, this will change to support dynamic loading of contracts with versioning +and signing constraints, but for now this is how it's written. We have four fields in our state: -* ``issuance``: a reference to a specific piece of commercial paper at a party -* ``owner``: the public key of the current owner. This is the same concept as seen in Bitcoin: the public key has no +* ``issuance``, a reference to a specific piece of commercial paper issued by some party. +* ``owner``, the public key of the current owner. This is the same concept as seen in Bitcoin: the public key has no attached identity and is expected to be one-time-use for privacy reasons. However, unlike in Bitcoin, we model - ownership at the level of individual contracts rather than as a platform-level concept as we envisage many + ownership at the level of individual states rather than as a platform-level concept as we envisage many (possibly most) contracts on the platform will not represent "owner/issuer" relationships, but "party/party" relationships such as a derivative contract. -* ``faceValue``: an ``Amount``, which wraps an integer number of pennies and a currency. -* ``maturityDate``: an `Instant `_, which is a type +* ``faceValue``, an ``Amount>``, which wraps an integer number of pennies and a currency that is + specific to some issuer (e.g. a regular bank, a central bank, etc). You can read more about this very common + type in :doc:`transaction-data-types`. +* ``maturityDate``, an `Instant `_, which is a type from the Java 8 standard time library. It defines a point on the timeline. States are immutable, and thus the class is defined as immutable as well. The ``data`` modifier in the Kotlin version @@ -175,7 +197,7 @@ be used to create variants of the original object. Data classes are similar to c familiar with that language. The ``withoutOwner`` method uses the auto-generated copy method to return a version of the state with the owner public key blanked out: this will prove useful later. -The Java code compiles to the same bytecode as the Kotlin version, but as you can see, is much more verbose. +The Java code compiles to almost identical bytecode as the Kotlin version, but as you can see, is much more verbose. Commands -------- @@ -183,10 +205,11 @@ Commands The logic for a contract may vary depending on what stage of a lifecycle it is automating. So it can be useful to pass additional data into the contract code that isn't represented by the states which exist permanently in the ledger. -For this purpose we have commands. Often, they don't need to contain any data at all, they just need to exist. A command +For this purpose we have commands. Often they don't need to contain any data at all, they just need to exist. A command is a piece of data associated with some *signatures*. By the time the contract runs the signatures have already been checked, so from the contract code's perspective, a command is simply a data structure with a list of attached -public keys. Each key had a signature proving that the corresponding private key was used to sign. +public keys. Each key had a signature proving that the corresponding private key was used to sign. Because of this +approach contracts never actually interact or work with digital signatures directly. Let's define a few commands now: @@ -194,10 +217,10 @@ Let's define a few commands now: .. sourcecode:: kotlin - interface Commands : Command { - object Move : Commands - object Redeem : Commands - object Issue : Commands + interface Commands : CommandData { + class Move : TypeOnlyCommandData(), Commands + class Redeem : TypeOnlyCommandData(), Commands + class Issue : TypeOnlyCommandData(), Commands } @@ -226,9 +249,10 @@ Let's define a few commands now: } } -The ``object`` keyword in Kotlin just defines a singleton object. As the commands don't need any additional data in our -case, they can be empty and we just use their type as the important information. Java has no syntax for declaring -singletons, so we just define a class that considers any other instance to be equal and that's good enough. +We define a simple grouping interface or static class, this gives us a type that all our commands have in common, +then we go ahead and create three commands: ``Move``, ``Redeem``, ``Issue``. ``TypeOnlyCommandData`` is a helpful utility +for the case when there's no data inside the command; only the existence matters. It defines equals and hashCode +such that any instances always compare equal and hash to the same value. The verify function ------------------- @@ -246,23 +270,28 @@ run two contracts one time each: Cash and CommercialPaper. .. sourcecode:: kotlin - override fun verify(tx: TransactionForVerification) { + override fun verify(tx: TransactionForContract) { // Group by everything except owner: any modification to the CP at all is considered changing it fundamentally. - val groups = tx.groupStates() { it: State -> it.withoutOwner() } + val groups = tx.groupStates(State::withoutOwner) + + // There are two possible things that can be done with this CP. The first is trading it. The second is redeeming + // it for cash on or after the maturity date. val command = tx.commands.requireSingleCommand() .. sourcecode:: java @Override - public void verify(@NotNull TransactionForVerification tx) { + public void verify(TransactionForContract tx) { List> groups = tx.groupStates(State.class, State::withoutOwner); AuthenticatedObject cmd = requireSingleCommand(tx.getCommands(), Commands.class); We start by using the ``groupStates`` method, which takes a type and a function. State grouping is a way of ensuring your contract can handle multiple unrelated states of the same type in the same transaction, which is needed for -splitting/merging of assets, atomic swaps and so on. The second line does what the code suggests: it searches for -a command object that inherits from the ``CommercialPaper.Commands`` supertype, and either returns it, or throws an -exception if there's zero or more than one such command. +splitting/merging of assets, atomic swaps and so on. More on this next. + +The second line does what the code suggests: it searches for a command object that inherits from the +``CommercialPaper.Commands`` supertype, and either returns it, or throws an exception if there's zero or more than one +such command. Using state groups ------------------ @@ -297,12 +326,12 @@ inputs e.g. because she received the dollars in two payments. The input and outp the cash smart contract must consider the pounds and the dollars separately because they are not fungible: they cannot be merged together. So we have two groups: A and B. -The ``TransactionForVerification.groupStates`` method handles this logic for us: firstly, it selects only states of the +The ``TransactionForContract.groupStates`` method handles this logic for us: firstly, it selects only states of the given type (as the transaction may include other types of state, such as states representing bond ownership, or a multi-sig state) and then it takes a function that maps a state to a grouping key. All states that share the same key are grouped together. In the case of the cash example above, the grouping key would be the currency. -In other kinds of contract, we don't want CP to be fungible: merging and splitting is (in our example) not allowed. +In this kind of contract we don't want CP to be fungible: merging and splitting is (in our example) not allowed. So we just use a copy of the state minus the owner field as the grouping key. Here are some code examples: @@ -372,51 +401,53 @@ logic. .. sourcecode:: kotlin - val time = tx.time - for (group in groups) { + val timestamp: Timestamp? = tx.timestamp + + for ((inputs, outputs, key) in groups) { when (command.value) { is Commands.Move -> { - val input = group.inputs.single() + val input = inputs.single() requireThat { - "the transaction is signed by the owner of the CP" by (command.signers.contains(input.owner)) + "the transaction is signed by the owner of the CP" by (input.owner in command.signers) "the state is propagated" by (group.outputs.size == 1) + // Don't need to check anything else, as if outputs.size == 1 then the output is equal to + // the input ignoring the owner field due to the grouping. } } is Commands.Redeem -> { - val input = group.inputs.single() - val received = tx.outStates.sumCashBy(input.owner) - if (time == null) throw IllegalArgumentException("Redemption transactions must be timestamped") + // Redemption of the paper requires movement of on-ledger cash. + val input = inputs.single() + val received = tx.outputs.sumCashBy(input.owner) + val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped") requireThat { - "the paper must have matured" by (time > input.maturityDate) + "the paper must have matured" by (time >= input.maturityDate) "the received amount equals the face value" by (received == input.faceValue) - "the paper must be destroyed" by group.outputs.isEmpty() - "the transaction is signed by the owner of the CP" by (command.signers.contains(input.owner)) + "the paper must be destroyed" by outputs.isEmpty() + "the transaction is signed by the owner of the CP" by (input.owner in command.signers) } } is Commands.Issue -> { - val output = group.outputs.single() - if (time == null) throw IllegalArgumentException("Issuance transactions must be timestamped") + val output = outputs.single() + val time = timestamp?.before ?: throw IllegalArgumentException("Issuances must be timestamped") requireThat { // Don't allow people to issue commercial paper under other entities identities. - "the issuance is signed by the claimed issuer of the paper" by - (command.signers.contains(output.issuance.party.owningKey)) - "the face value is not zero" by (output.faceValue.pennies > 0) - "the maturity date is not in the past" by (time < output.maturityDate ) + "output states are issued by a command signer" by (output.issuance.party.owningKey in command.signers) + "output values sum to more than the inputs" by (output.faceValue.quantity > 0) + "the maturity date is not in the past" by (time < output.maturityDate) // Don't allow an existing CP state to be replaced by this issuance. - "there is no input state" by group.inputs.isEmpty() + "can't reissue an existing state" by inputs.isEmpty() } } - // TODO: Think about how to evolve contracts over time with new commands. else -> throw IllegalArgumentException("Unrecognised command") } } .. sourcecode:: java - Instant time = tx.getTime(); // Can be null/missing. + Timestamp time = tx.getTimestamp(); // Can be null/missing. for (InOutGroup group : groups) { List inputs = group.getInputs(); List outputs = group.getOutputs(); @@ -424,34 +455,20 @@ logic. // For now do not allow multiple pieces of CP to trade in a single transaction. Study this more! State input = single(filterIsInstance(inputs, State.class)); - requireThat(require -> { - require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner())); - return Unit.INSTANCE; - }); + checkState(cmd.getSigners().contains(input.getOwner()), "the transaction is signed by the owner of the CP"); if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) { - requireThat(require -> { - require.by("the state is propagated", outputs.size() == 1); - return Unit.INSTANCE; - }); + checkState(outputs.size() == 1, "the state is propagated"); // Don't need to check anything else, as if outputs.size == 1 then the output is equal to // the input ignoring the owner field due to the grouping. } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) { - TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary); - Instant time = null == timestampCommand - ? null - : timestampCommand.getBefore(); + checkNotNull(timem "must be timestamped"); + Instant t = time.getBefore(); Amount> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner()); - requireThat(require -> { - require.by("must be timestamped", timestampCommand != null); - require.by("received amount equals the face value: " - + received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue())); - require.by("the paper must have matured", time != null && !time.isBefore(input.getMaturityDate())); - require.by("the received amount equals the face value", input.getFaceValue().equals(received)); - require.by("the paper must be destroyed", outputs.isEmpty()); - return Unit.INSTANCE; - }); + checkState(received.equals(input.getFaceValue()), "received amount equals the face value"); + checkState(t.isBefore(input.getMaturityDate(), "the paper must have matured"); + checkState(outputs.isEmpty(), "the paper must be destroyed"); } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) { // .. etc .. (see Kotlin for full definition) } @@ -462,7 +479,9 @@ This loop is the core logic of the contract. The first line simply gets the timestamp out of the transaction. Timestamping of transactions is optional, so a time may be missing here. We check for it being null later. -.. note:: In the Kotlin version, as long as we write a comparison with the transaction time first, the compiler will +.. note:: In future timestamping may be mandatory for all transactions. + +.. warning:: In the Kotlin version as long as we write a comparison with the transaction time first the compiler will verify we didn't forget to check if it's missing. Unfortunately due to the need for smooth Java interop, this check won't happen if we write e.g. ``someDate > time``, it has to be ``time < someDate``. So it's good practice to always write the transaction timestamp first. @@ -471,19 +490,19 @@ The first line (first three lines in Java) impose a requirement that there be a this group. We do not allow multiple units of CP to be split or merged even if they are owned by the same owner. The ``single()`` method is a static *extension method* defined by the Kotlin standard library: given a list, it throws an exception if the list size is not 1, otherwise it returns the single item in that list. In Java, this appears as a -regular static method of the type familiar from many FooUtils type singleton classes. In Kotlin, it appears as a -method that can be called on any JDK list. The syntax is slightly different but behind the scenes, the code compiles -to the same bytecodes. +regular static method of the type familiar from many FooUtils type singleton classes and we have statically imported it +here. In Kotlin, it appears as a method that can be called on any JDK list. The syntax is slightly different but +behind the scenes, the code compiles to the same bytecodes. Next, we check that the transaction was signed by the public key that's marked as the current owner of the commercial paper. Because the platform has already verified all the digital signatures before the contract begins execution, all we have to do is verify that the owner's public key was one of the keys that signed the transaction. The Java code -is straightforward. The Kotlin version looks a little odd: we have a *requireThat* construct that looks like it's +is straightforward: we are simply using the ``Preconditions.checkState`` method from Guava. The Kotlin version looks a little odd: we have a *requireThat* construct that looks like it's built into the language. In fact *requireThat* is an ordinary function provided by the platform's contract API. Kotlin supports the creation of *domain specific languages* through the intersection of several features of the language, and we use it here to support the natural listing of requirements. To see what it compiles down to, look at the Java version. Each ``"string" by (expression)`` statement inside a ``requireThat`` turns into an assertion that the given expression is -true, with an exception being thrown that contains the string if not. It's just another way to write out a regular +true, with an ``IllegalStateException`` being thrown that contains the string if not. It's just another way to write out a regular assertion, but with the English-language requirement being put front and center. Next, we take one of two paths, depending on what the type of the command object is. @@ -500,19 +519,19 @@ If the command is a ``Redeem`` command, then the requirements are more complex: 3. The commercial paper must *not* be propagated by this transaction: it must be deleted, by the group having no output state. This prevents the same CP being considered redeemable multiple times. -To calculate how much cash is moving, we use the ``sumCashOrNull`` utility method. Again, this is an extension method, +To calculate how much cash is moving, we use the ``sumCashBy`` utility function. Again, this is an extension function, so in Kotlin code it appears as if it was a method on the ``List`` type even though JDK provides no such -method. In Java we see its true nature: it is actually a static method named ``CashKt.sumCashOrNull``. This method simply -returns an ``Amount`` object containing the sum of all the cash states in the transaction output, or null if there were -no such states *or* if there were different currencies represented in the outputs! So we can see that this contract -imposes a limitation on the structure of a redemption transaction: you are not allowed to move currencies in the same -transaction that the CP does not involve. This limitation could be addressed with better APIs, if it were to be a -real limitation. +method. In Java we see its true nature: it is actually a static method named ``CashKt.sumCashBy``. This method simply +returns an ``Amount`` object containing the sum of all the cash states in the transaction outputs that are owned by +that given public key, or throws an exception if there were no such states *or* if there were different currencies +represented in the outputs! So we can see that this contract imposes a limitation on the structure of a redemption +transaction: you are not allowed to move currencies in the same transaction that the CP does not involve. This +limitation could be addressed with better APIs, if it were to be a real limitation. Finally, we support an ``Issue`` command, to create new instances of commercial paper on the ledger. It likewise enforces various invariants upon the issuance. -This contract is extremely simple and does not implement all the business logic a real commercial paper lifecycle +This contract is simple and does not implement all the business logic a real commercial paper lifecycle management program would. For instance, there is no logic requiring a signature from the issuer for redemption: it is assumed that any transfer of money that takes place at the same time as redemption is good enough. Perhaps that is something that should be tightened. Likewise, there is no logic handling what happens if the issuer has gone @@ -525,172 +544,15 @@ How to test your contract ------------------------- Of course, it is essential to unit test your new nugget of business logic to ensure that it behaves as you expect. -Although you can write traditional unit tests in Java, the platform also provides a *domain specific language* -(DSL) for writing contract unit tests that automates many of the common patterns. This DSL builds on top of JUnit yet -is a Kotlin DSL, and therefore this section will not show Java equivalent code (for Java unit tests you would not -benefit from the DSL and would write them by hand). +As contract code is just a regular Java function you could write out the logic entirely by hand in the usual +manner. But this would be inconvenient, and then you'd get bored of writing tests and that would be bad: you +might be tempted to skip a few. -We start by defining a new test class, with a basic CP state: +To make contract testing more convenient Corda provides a language-like API for both Kotlin and Java that lets +you easily construct chains of transactions and verify that they either pass validation, or fail with a particular +error message. -.. container:: codeset - - .. sourcecode:: kotlin - - class CommercialPaperTests { - val PAPER_1 = CommercialPaper.State( - issuance = InstitutionReference(MEGA_CORP, OpaqueBytes.of(123)), - owner = MEGA_CORP_KEY, - faceValue = 1000.DOLLARS, - maturityDate = TEST_TX_TIME + 7.days - ) - - @Test - fun key_mismatch_at_issue() { - transactionGroup { - transaction { - output { PAPER_1 } - arg(DUMMY_PUBKEY_1) { CommercialPaper.Commands.Issue() } - } - - expectFailureOfTx(1, "signed by the claimed issuer") - } - } - } - -We start by defining a commercial paper state. It will be owned by a pre-defined unit test party, affectionately -called ``MEGA_CORP`` (this constant, along with many others, is defined in ``TestUtils.kt``). Due to Kotin's extensive -type inference, many types are not written out explicitly in this code and it has the feel of a scripting language. -But the types are there, and you can ask IntelliJ to reveal them by pressing Alt-Enter on a "val" or "var" and selecting -"Specify type explicitly". - -There are a few things that are unusual here: - -* We can specify quantities of money by writing 1000.DOLLARS or 1000.POUNDS -* We can specify quantities of time by writing 7.days -* We can add quantities of time to the TEST_TX_TIME constant, which merely defines an arbitrary java.time.Instant - -If you examine the code in the actual repository, you will also notice that it makes use of method names with spaces -in them by surrounding the name with backticks, rather than using underscores. We don't show this here as it breaks the -doc website's syntax highlighting engine. - -The ``1000.DOLLARS`` construct is quite simple: Kotlin allows you to define extension functions on primitive types like -Int or Double. So by writing 7.days, for instance, the compiler will emit a call to a static method that takes an int -and returns a ``java.time.Duration``. - -As this is JUnit, we must remember to annotate each test method with @Test. Let's examine the contents of the first test. -We are trying to check that it's not possible for just anyone to issue commercial paper in MegaCorp's name. That would -be bad! - -The ``transactionGroup`` function works the same way as the ``requireThat`` construct above. - -.. note:: This DSL is an example of what Kotlin calls a type safe builder, which you can read about in `the - documentation for builders `_. You can mix and match - ordinary code inside such DSLs so please read the linked page to make sure you fully understand what they are capable - of. - -The code block that follows it is run in the scope of a freshly created ``TransactionGroupForTest`` object, which assists -you with building little transaction graphs and verifying them as a whole. Here, our "group" only actually has a -single transaction in it, with a single output, no inputs, and an Issue command signed by ``DUMMY_PUBKEY_1`` which is just -an arbitrary public key. As the paper claims to be issued by ``MEGA_CORP``, this doesn't match and should cause a -failure. The ``expectFailureOfTx`` method takes a 1-based index (in this case we expect the first transaction to fail) -and a string that should appear in the exception message. Then it runs the ``TransactionGroup.verify()`` method to -invoke all the involved contracts. - -It's worth bearing in mind that even though this code may look like a totally different language to normal Kotlin or -Java, it's actually not, and so you can embed arbitrary code anywhere inside any of these blocks. - -Let's set up a full trade and ensure it works: - -.. container:: codeset - - .. sourcecode:: kotlin - - // Generate a trade lifecycle with various parameters. - private fun trade(redemptionTime: Instant = TEST_TX_TIME + 8.days, - aliceGetsBack: Amount = 1000.DOLLARS, - destroyPaperAtRedemption: Boolean = true): TransactionGroupForTest { - val someProfits = 1200.DOLLARS - return transactionGroup { - roots { - transaction(900.DOLLARS.CASH owned_by ALICE label "alice's $900") - transaction(someProfits.CASH owned_by MEGA_CORP_KEY label "some profits") - } - - // Some CP is issued onto the ledger by MegaCorp. - transaction { - output("paper") { PAPER_1 } - arg(MEGA_CORP_KEY) { CommercialPaper.Commands.Issue() } - } - - // 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 { - input("paper") - input("alice's $900") - output { 900.DOLLARS.CASH owned_by MEGA_CORP_KEY } - output("alice's paper") { PAPER_1 owned_by ALICE } - arg(ALICE) { Cash.Commands.Move } - arg(MEGA_CORP_KEY) { CommercialPaper.Commands.Move } - } - - // 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(time = redemptionTime) { - input("alice's paper") - input("some profits") - - output { aliceGetsBack.CASH owned_by ALICE } - output { (someProfits - aliceGetsBack).CASH owned_by MEGA_CORP_KEY } - if (!destroyPaperAtRedemption) - output { PAPER_1 owned_by ALICE } - - arg(MEGA_CORP_KEY) { Cash.Commands.Move } - arg(ALICE) { CommercialPaper.Commands.Redeem } - } - } - } - -In this example we see some new features of the DSL: - -* The ``roots`` construct. Sometimes you don't want to write transactions that laboriously issue everything you need - in a formally correct way. Inside ``roots`` you can create a bunch of states without any contract checking what you're - doing. As states may not exist outside of transactions, each line inside defines a fake/invalid transaction with the - given output states, which may be *labelled* with a short string. Those labels can be used later to join transactions - together. -* The ``.CASH`` suffix. This is a part of the unit test DSL specific to the cash contract. It takes a monetary amount - like 1000.DOLLARS and then wraps it in a cash ledger state, with some fake data. -* The owned_by `infix function `_. This is just - a normal function that we're allowed to write in a slightly different way, which returns a copy of the cash state - with the owner field altered to be the given public key. ``ALICE`` is a constant defined by the test utilities that - is, like ``DUMMY_PUBKEY_1``, just an arbitrary keypair. -* We are now defining several transactions that chain together. We can optionally label any output we create. Obviously - then, the ``input`` method requires us to give the label of some other output that it connects to. -* The ``transaction`` function can also be given a time, to override the default timestamp on a transaction. - -The ``trade`` function is not itself a unit test. Instead it builds up a trade/transaction group, with some slight -differences depending on the parameters provided (Kotlin allows parameters to have default values). Then it returns -it, unexecuted. - -We use it like this: - -.. container:: codeset - - .. sourcecode:: kotlin - - @Test - fun ok() { - trade().verify() - } - - @Test - fun not_matured_at_redemption() { - trade(redemptionTime = TEST_TX_TIME + 2.days).expectFailureOfTx(3, "must have matured") - } - -That's pretty simple: we just call ``verify`` in order to check all the transactions in the group. If any are invalid, -an exception will be thrown indicating which transaction failed and why. In the second case, we call ``expectFailureOfTx`` -again to ensure the third transaction fails with a message that contains "must have matured" (it doesn't have to be -the exact message). +Testing contracts with this domain specific language is covered in the separate tutorial, :doc:`tutorial-test-dsl`. Adding a generation API to your contract @@ -719,16 +581,17 @@ a method to wrap up the issuance process: .. sourcecode:: kotlin - fun generateIssue(issuance: InstitutionReference, faceValue: Amount, maturityDate: Instant): TransactionBuilder { + fun generateIssue(issuance: PartyAndReference, faceValue: Amount>, maturityDate: Instant, + notary: Party): TransactionBuilder { val state = State(issuance, issuance.party.owningKey, faceValue, maturityDate) - return TransactionBuilder(state, WireCommand(Commands.Issue, issuance.party.owningKey)) + return TransactionBuilder(notary = notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey)) } We take a reference that points to the issuing party (i.e. the caller) and which can contain any internal -bookkeeping/reference numbers that we may require. Then the face value of the paper, and the maturity date. It -returns a ``TransactionBuilder``. A ``TransactionBuilder`` is one of the few mutable classes the platform provides. -It allows you to add inputs, outputs and commands to it and is designed to be passed around, potentially between -multiple contracts. +bookkeeping/reference numbers that we may require. The reference field is an ideal place to put (for example) a +join key. Then the face value of the paper, and the maturity date. It returns a ``TransactionBuilder``. +A ``TransactionBuilder`` is one of the few mutable classes the platform provides. It allows you to add inputs, +outputs and commands to it and is designed to be passed around, potentially between multiple contracts. .. note:: Generation methods should ideally be written to compose with each other, that is, they should take a ``TransactionBuilder`` as an argument instead of returning one, unless you are sure it doesn't make sense to @@ -737,17 +600,22 @@ multiple contracts. an issuer should issue the CP (starting out owned by themselves), and then sell it in a separate transaction. The function we define creates a ``CommercialPaper.State`` object that mostly just uses the arguments we were given, -but it fills out the owner field of the state to be the same public key as the issuing party. If the caller wants -to issue CP onto the ledger that's immediately owned by someone else, they'll have to create the state themselves. +but it fills out the owner field of the state to be the same public key as the issuing party. -The returned partial transaction has a ``WireCommand`` object as a parameter. This is a container for any object -that implements the ``Command`` interface, along with a key that is expected to sign this transaction. In this case, +The returned partial transaction has a ``Command`` object as a parameter. This is a container for any object +that implements the ``CommandData`` interface, along with a list of keys that are expected to sign this transaction. In this case, issuance requires that the issuing party sign, so we put the key of the party there. -The ``TransactionBuilder`` constructor we used above takes a variable argument list for convenience. You can pass in -any ``ContractStateRef`` (input), ``ContractState`` (output) or ``Command`` objects and it'll build up the transaction +The ``TransactionBuilder`` has a convenience ``withItems`` method that takes a variable argument list. You can pass in +any ``StateAndRef`` (input), ``ContractState`` (output) or ``Command`` objects and it'll build up the transaction for you. +There's one final thing to be aware of: we ask the caller to select a *notary* that controls this state and +prevents it from being double spent. You can learn more about this topic in the :doc:`consensus` article. + +.. note:: For now, don't worry about how to pick a notary. More infrastructure will come later to automate this + decision for you. + What about moving the paper, i.e. reassigning ownership to someone else? .. container:: codeset @@ -755,9 +623,9 @@ What about moving the paper, i.e. reassigning ownership to someone else? .. sourcecode:: kotlin fun generateMove(tx: TransactionBuilder, paper: StateAndRef, newOwner: PublicKey) { - tx.addInputState(paper.ref) - tx.addOutputState(paper.state.copy(owner = newOwner)) - tx.addArg(WireCommand(Commands.Move, paper.state.owner)) + tx.addInputState(paper) + tx.addOutputState(paper.state.data.withOwner(newOwner)) + tx.addCommand(Command(Commands.Move(), paper.state.data.owner)) } Here, the method takes a pre-existing ``TransactionBuilder`` and adds to it. This is correct because typically @@ -769,6 +637,10 @@ The paper is given to us as a ``StateAndRef`` object. Thi a small object that has a (copy of) a state object, and also the (txhash, index) that indicates the location of this state on the ledger. +We add the existing paper state as an input, the same paper state with the owner field adjusted as an output, +and finally a move command that has the old owner's public key: this is what forces the current owner's signature +to be present on the transaction, and is what's checked by the contract. + Finally, we can do redemption. .. container:: codeset @@ -776,77 +648,82 @@ Finally, we can do redemption. .. sourcecode:: kotlin @Throws(InsufficientBalanceException::class) - fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef, wallet: List>) { + fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef, wallet: Wallet) { // Add the cash movement using the states in our wallet. - Cash().generateSpend(tx, paper.state.faceValue, paper.state.owner, wallet) - tx.addInputState(paper.ref) - tx.addArg(WireCommand(CommercialPaper.Commands.Redeem, paper.state.owner)) + Cash().generateSpend(tx, paper.state.data.faceValue.withoutIssuer(), paper.state.data.owner, wallet.statesOfType()) + tx.addInputState(paper) + tx.addCommand(Command(Commands.Redeem(), paper.state.data.owner)) } Here we can see an example of composing contracts together. When an owner wishes to redeem the commercial paper, the issuer (i.e. the caller) must gather cash from its wallet and send the face value to the owner of the paper. -.. note:: **Exercise for the reader**: In this early, simplified model of CP there is no built in support - for rollover. Extend the contract code to support rollover as well as redemption (reissuance of the paper with a - higher face value without any transfer of cash) +.. note:: This contract has no explicit concept of rollover. -The *wallet* is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of cash states that are +The *wallet* is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of states (such as cash) that are owned by the caller. Here, we use the wallet to update the partial transaction we are handed with a movement of cash from the issuer of the commercial paper to the current owner. If we don't have enough quantity of cash in our wallet, -an exception is thrown. And then we add the paper itself as an input, but, not an output (as we wish to delete it -from the ledger permanently). Finally, we add a Redeem command that should be signed by the owner of the commercial -paper. +an exception is thrown. Then we add the paper itself as an input, but, not an output (as we wish to remove it +from the ledger). Finally, we add a Redeem command that should be signed by the owner of the commercial paper. + +.. warning:: The amount we pass to the ``generateSpend`` function has to be treated first with ``withoutIssuer``. + This reflects the fact that the way we handle issuer constraints is still evolving; the commercial paper + contract requires payment in the form of a currency issued by a specific party (e.g. the central bank, + or the issuers own bank perhaps). But the wallet wants to assemble spend transactions using cash states from + any issuer, thus we must strip it here. This represents a design mismatch that we will resolve in future + versions with a more complete way to express issuer constraints. A ``TransactionBuilder`` is not by itself ready to be used anywhere, so first, we must convert it to something that is recognised by the network. The most important next step is for the participating entities to sign it using the ``signWith()`` method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the signature inside the ``TransactionBuilder``. Once all parties have signed, you can call ``TransactionBuilder.toSignedTransaction()`` -to get a ``SignedTransaction`` object. This is an immutable form of the transaction that's ready for *timestamping*, -which can be done using a ``TimestamperClient``. To learn more about that, please refer to the -:doc:`protocol-state-machines` document. +to get a ``SignedTransaction`` object. You can see how transactions flow through the different stages of construction by examining the commercial paper unit tests. -Non-asset-oriented based smart contracts ----------------------------------------- +How multi-party transactions are constructed and transmitted +------------------------------------------------------------ -It is important to distinguish between the idea of a legal contract vs a code contract. In this document we use the -term *contract* as a shorthand for code contract: a small module of widely shared, simultaneously executed business -logic that uses standardised APIs and runs in a sandbox. +OK, so now we know how to define the rules of the ledger, and we know how to construct transactions that satisfy +those rules ... and if all we were doing was maintaining our own data that might be enough. But we aren't: Corda +is about keeping many different parties all in sync with each other. + +In a classical blockchain system all data is transmitted to everyone and if you want to do something fancy, like +a multi-party transaction, you're on your own. In Corda data is transmitted only to parties that need it and +multi-party transactions are a way of life, so we provide lots of support for managing them. + +You can learn how transactions are moved between peers and taken through the build-sign-notarise-broadcast +process in a separate tutorial, :doc:`protocol-state-machines`. + +Non-asset-oriented smart contracts +---------------------------------- Although this tutorial covers how to implement an owned asset, there is no requirement that states and code contracts *must* be concerned with ownership of an asset. It is better to think of states as representing useful facts about the -world, and (code) contracts as imposing logical relations on how facts combine to produce new facts. +world, and (code) contracts as imposing logical relations on how facts combine to produce new facts. Alternatively +you can imagine that states are like rows in a relational database and contracts are like stored procedures and +relational constraints. -For example, in the case that the transfer of an asset cannot be performed entirely on-ledger, one possible usage of -the model is to implement a delivery-vs-payment lifecycle in which there is a state representing an intention to trade -and two other states that can be interpreted by off-ledger platforms as firm instructions to move the respective asset -or cash - and a final state in which the exchange is marked as complete. The key point here is that the two off-platform -instructions form pa rt of the same Transaction and so either both are signed (and can be processed by the off-ledger -systems) or neither are. +When writing a contract that handles deal-like entities rather than asset-like entities, you may wish to refer +to ":doc:`contract-irs`" and the accompanying source code. Whilst all the concepts are the same, deals are +typically not splittable or mergeable and thus you don't have to worry much about grouping of states. -As another example, consider multi-signature transactions, a feature which is commonly used in Bitcoin to implement -various kinds of useful protocols. This technique allows you to lock an asset to ownership of a group, in which a -threshold of signers (e.g. 3 out of 4) must all sign simultaneously to enable the asset to move. It is initially -tempting to simply add this as another feature to each existing contract which someone might want to treat in this way. -But that could lead to unnecessary duplication of work. +Making things happen at a particular time +----------------------------------------- -A better approach is to model the fact of joint ownership as a new contract with its own state. In this approach, to -lock up your commercial paper under multi-signature ownership you would make a transaction that looks like this: - -* **Input**: the CP state -* **Output**: a multi-sig state that contains the list of keys and the signing threshold desired (e.g. 3 of 4). The state has a hash of H. -* **Output**: the same CP state, with a marker that says a state with hash H must exist in any transaction that spends it. - -The CP contract then needs to be extended only to verify that a state with the required hash is present as an input. -The logic that implements measurement of the threshold, different signing combinations that may be allowed etc can then -be implemented once in a separate contract, with the controlling data being held in the named state. - -Future versions of the prototype will explore these concepts in more depth. +It would be nice if you could program your node to automatically redeem your commercial paper as soon as it matures. +Corda provides a way for states to advertise scheduled events that should occur in future. Whilst this information +is by default ignored, if the corresponding *Cordapp* is installed and active in your node, and if the state is +considered relevant by your wallet (e.g. because you own it), then the node can automatically begin the process +of creating a transaction and taking it through the life cycle. You can learn more about this in the article +":doc:`event-scheduling`". Clauses ------- -Instead of structuring contracts as a single entity, they can be broken down into reusable chunks known as clauses. -This idea is addressed in the next tutorial, ":doc:`tutorial-contract-clauses`". \ No newline at end of file +It is typical for slightly different contracts to have lots of common logic that can be shared. For example, the +concept of being issued, being exited and being upgraded are all usually required in any contract. Corda calls these +frequently needed chunks of logic "clauses", and they can simplify development considerably. + +Clauses and how to use them are addressed in the next tutorial, ":doc:`tutorial-contract-clauses`". \ No newline at end of file diff --git a/docs/build/html/_static/corda-introductory-whitepaper.pdf b/docs/build/html/_static/corda-introductory-whitepaper.pdf index 7bbf2a1a08..a43f57e18b 100644 Binary files a/docs/build/html/_static/corda-introductory-whitepaper.pdf and b/docs/build/html/_static/corda-introductory-whitepaper.pdf differ diff --git a/docs/build/html/api/alltypes/index.html b/docs/build/html/api/alltypes/index.html index 17f1dd3c5b..b6864614ea 100644 --- a/docs/build/html/api/alltypes/index.html +++ b/docs/build/html/api/alltypes/index.html @@ -117,6 +117,13 @@ for ensuring code runs on the right thread, and also for unit testing.

+com.r3corda.core.contracts.clauses.AllComposition + +

Compose a number of clauses, such that all of the clauses must run for verification to pass.

+ + + + com.r3corda.core.messaging.AllPossibleRecipients

A special base class for the set of all possible recipients, without having to identify who they all are.

@@ -139,6 +146,13 @@ amount used in whatever underlying thing the amount represents.

+com.r3corda.core.contracts.clauses.AnyComposition + +

Compose a number of clauses, such that any number of the clauses can run.

+ + + + 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 @@ -240,6 +254,14 @@ Bilateral states are used in close-out netting.

+com.r3corda.protocols.BroadcastTransactionProtocol + +

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+ + + + com.r3corda.core.contracts.BusinessCalendar

A business calendar performs date calculations that take into account national holidays and weekends. This is a @@ -300,7 +322,6 @@ the same transaction.

com.r3corda.core.contracts.clauses.Clause -

A clause that can be matched as part of execution of a contract.

@@ -318,7 +339,7 @@ the same transaction.

-com.r3corda.node.services.monitor.ClientToServiceCommand +com.r3corda.core.contracts.ClientToServiceCommand

A command from the monitoring client, to the node.

@@ -371,6 +392,8 @@ the same transaction.

com.r3corda.core.contracts.Commodity +

Class representing a commodity, as an equivalent to the Currency class. This exists purely to enable the +CommodityContract contract, and is likely to change in future.

@@ -386,6 +409,21 @@ internal accounting by the issuer (it might be, for example, a warehouse and/or +com.r3corda.core.contracts.clauses.CompositeClause + +

Abstract supertype for clauses which compose other clauses together in some logical manner.

+ + + + +com.r3corda.core.contracts.clauses.ConcreteClause + +

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+ + + + com.r3corda.node.servlets.Config

Primary purpose is to install Kotlin extensions for Jackson ObjectMapper so data classes work @@ -727,6 +765,20 @@ attachments are saved to local storage automatically.

+com.r3corda.protocols.FinalityProtocol + +

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+ + + + +com.r3corda.core.contracts.clauses.FirstComposition + +

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+ + + + com.r3corda.core.contracts.Fix

A Fix represents a named interest rate, on a given day, for a given duration. It can be embedded in a tx.

@@ -812,24 +864,12 @@ container), shares of the same class in a specific company are fungible and coun -com.r3corda.core.contracts.clauses.GroupClause - - - - - com.r3corda.core.contracts.clauses.GroupClauseVerifier -com.r3corda.core.contracts.clauses.GroupVerify - - - - - com.r3corda.demos.IRSDemoNode @@ -950,14 +990,6 @@ states relevant to us into a database and once such a wallet is implemented, thi -com.r3corda.core.contracts.clauses.InterceptorClause - -

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.

- - - - com.r3corda.contracts.InterestRateSwap

The Interest Rate Swap class. For a quick overview of what an IRS is, see here - http://www.pimco.co.uk/EN/Education/Pages/InterestRateSwapsBasics1-08.aspx (no endorsement). @@ -1135,12 +1167,6 @@ with the commands from the wire, and verified/looked up.

-com.r3corda.core.contracts.clauses.MatchBehaviour - - - - - com.r3corda.core.messaging.Message

A message is defined, at this level, to be a (topic, timestamp, byte arrays) triple, where the topic is a string in @@ -2024,14 +2050,6 @@ contained within.

-com.r3corda.core.contracts.clauses.SingleClause - -

A single verifiable clause. By default always matches, continues to the next clause when matched and errors -if not matched.

- - - - com.r3corda.core.messaging.SingleMessageRecipient

A base class for the case of point-to-point messages

@@ -2039,12 +2057,6 @@ if not matched.

-com.r3corda.core.contracts.clauses.SingleVerify - - - - - com.r3corda.core.serialization.SingletonSerializationToken

A class representing a SerializationToken for some object that is not serializable but can be looked up @@ -2084,7 +2096,7 @@ Points at which polynomial pieces connect are known as knots.

com.r3corda.node.services.statemachine.StateMachineManager -

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. +

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-conserve-amount/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-conserve-amount/index.html index 245d4d3bcd..c635939f00 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-conserve-amount/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-conserve-amount/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Cash / Clauses / ConserveAmount

ConserveAmount

-class ConserveAmount : AbstractConserveAmount<State, Currency>
+class ConserveAmount : AbstractConserveAmount<State, Commands, Currency>


Constructors

@@ -21,29 +21,14 @@ -

Inherited Properties

+

Inherited Functions

+toString - - - - - - - - +open fun toString(): String
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-group/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-group/index.html index cdc1e69e52..2d44a03d70 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-group/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-group/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Cash / Clauses / Group

Group

-class Group : GroupClauseVerifier<State, Issued<Currency>>
+class Group : GroupClauseVerifier<State, Commands, Issued<Currency>>


Constructors

@@ -21,40 +21,14 @@ -

Properties

- - - - - - - - - - - - - - - -
-clauses -val clauses: <ERROR CLASS>
-ifMatched -val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-

Inherited Properties

+clause +val clause: Clause<S, C, K>
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
@@ -69,19 +43,5 @@ -

Inherited Functions

- - - - - - - -
-verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

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.

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/index.html index f3a0c53b8e..5438a43ba9 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Cash / Clauses / Issue

Issue

-class Issue : AbstractIssue<State, Currency>
+class Issue : AbstractIssue<State, Commands, Currency>


Constructors

@@ -28,7 +28,7 @@ requiredCommands -val requiredCommands: <ERROR CLASS>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -38,20 +38,6 @@ -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - sum val sum: List<S>.() -> Amount<Issued<T>> diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/required-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/required-commands.html index 6c0436f30f..330bb5d7e1 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/-issue/required-commands.html @@ -8,9 +8,9 @@

requiredCommands

-val requiredCommands: <ERROR CLASS>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/index.html index a3800a9b70..5d31495fab 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-clauses/index.html @@ -17,19 +17,19 @@ ConserveAmount -class ConserveAmount : AbstractConserveAmount<State, Currency> +class ConserveAmount : AbstractConserveAmount<State, Commands, Currency> Group -class Group : GroupClauseVerifier<State, Issued<Currency>> +class Group : GroupClauseVerifier<State, Commands, Issued<Currency>> Issue -class Issue : AbstractIssue<State, Currency> +class Issue : AbstractIssue<State, Commands, Currency> diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/exit-keys.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/exit-keys.html index ddaea07e8b..556fa9ec72 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/exit-keys.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/-state/exit-keys.html @@ -10,7 +10,8 @@ val exitKeys: <ERROR CLASS>
Overrides FungibleAsset.exitKeys
-

There must be an ExitCommand signed by these keys to destroy the amount

+

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.



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 index e58cdbd7ab..8ac2830424 100644 --- 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 @@ -51,7 +51,8 @@ is only intended for use by the issuer, and is not intended to be meaningful to exitKeys -val exitKeys: <ERROR CLASS>

There must be an ExitCommand signed by these keys to destroy the amount

+val exitKeys: <ERROR CLASS>

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/conserve-clause.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/conserve-clause.html index 0bef25ada9..e8b9b8ef5e 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/conserve-clause.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/conserve-clause.html @@ -8,7 +8,7 @@

conserveClause

-val conserveClause: AbstractConserveAmount<State, Currency>
+val conserveClause: AbstractConserveAmount<State, Commands, Currency>
Overrides OnLedgerAsset.conserveClause


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-cash/extract-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/extract-commands.html index 3f9030014c..82675eebcd 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/extract-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/extract-commands.html @@ -7,8 +7,8 @@ com.r3corda.contracts.asset / Cash / extractCommands

extractCommands

- -fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+ +fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
Overrides OnLedgerAsset.extractCommands


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 index d56c244c47..ec5fcd9c14 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-cash/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Cash

Cash

-class Cash : OnLedgerAsset<Currency, State>
+class Cash : OnLedgerAsset<Currency, Commands, State>

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 @@ -65,15 +65,9 @@ the same transaction.

-clauses - -val clauses: <ERROR CLASS> - - - conserveClause -val conserveClause: AbstractConserveAmount<State, Currency> +val conserveClause: AbstractConserveAmount<State, Commands, Currency> @@ -100,7 +94,7 @@ when sending out "change" from spending/exiting.

extractCommands -fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>> +fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>> @@ -128,16 +122,11 @@ when sending out "change" from spending/exiting.

fun generateMoveCommand(): Move - - -

Inherited Functions

- - +verify
-verify -open fun verify(tx: TransactionForContract): 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.asset/-cash/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-cash/verify.html new file mode 100644 index 0000000000..23ad34d393 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-cash/verify.html @@ -0,0 +1,20 @@ + + +Cash.verify - + + + +com.r3corda.contracts.asset / Cash / 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.contracts.asset/-commodity-contract/-clauses/-conserve-amount/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-conserve-amount/index.html index 32ce130022..736b13cce9 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-conserve-amount/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-conserve-amount/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / CommodityContract / Clauses / ConserveAmount

ConserveAmount

-class ConserveAmount : AbstractConserveAmount<State, Commodity>
+class ConserveAmount : AbstractConserveAmount<State, Commands, Commodity>

Standard clause for conserving the amount from input to output.



@@ -23,29 +23,14 @@
-

Inherited Properties

+

Inherited Functions

+toString - - - - - - - - +open fun toString(): String
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-group/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-group/index.html index abea699a6d..65431cf0f7 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-group/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-group/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / CommodityContract / Clauses / Group

Group

-class Group : GroupClauseVerifier<State, Issued<Commodity>>
+class Group : GroupClauseVerifier<State, Commands, Issued<Commodity>>

Grouping clause to extract input and output states into matched groups and then run a set of clauses over each group.


@@ -25,42 +25,14 @@ each group.

-

Properties

- - - - - - - - - - - - - - - -
-clauses -val clauses: <ERROR CLASS>
-ifMatched -val ifMatched: MatchBehaviour

The group clause is the only top level clause, so end after processing it. If there are any commands left -after this clause has run, the clause verifier will trigger an error.

-
-ifNotMatched -val ifNotMatched: MatchBehaviour

The group clause does not depend on any commands being present, so something has gone terribly wrong if -it doesnt match.

-

Inherited Properties

+clause +val clause: Clause<S, C, K>
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
@@ -76,19 +48,5 @@ it doesnt match.

-

Inherited Functions

- - - - - - - -
-verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

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.

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/index.html index 140d163d20..c3da1a5ec8 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / CommodityContract / Clauses / Issue

Issue

-class Issue : AbstractIssue<State, Commodity>
+class Issue : AbstractIssue<State, Commands, Commodity>

Standard issue clause, specialised to match the commodity issue command.



@@ -30,7 +30,7 @@ requiredCommands -val requiredCommands: <ERROR CLASS>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -40,20 +40,6 @@ -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - sum val sum: List<S>.() -> Amount<Issued<T>> diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/required-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/required-commands.html index b7b2471375..cef383ae16 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/-issue/required-commands.html @@ -8,9 +8,9 @@

requiredCommands

-val requiredCommands: <ERROR CLASS>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/index.html index 3d53a83a11..97b5404720 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-clauses/index.html @@ -25,14 +25,14 @@ conserved (output = input - exit)

ConserveAmount -class ConserveAmount : AbstractConserveAmount<State, Commodity>

Standard clause for conserving the amount from input to output.

+class ConserveAmount : AbstractConserveAmount<State, Commands, Commodity>

Standard clause for conserving the amount from input to output.

Group -class Group : GroupClauseVerifier<State, Issued<Commodity>>

Grouping clause to extract input and output states into matched groups and then run a set of clauses over +class Group : GroupClauseVerifier<State, Commands, Issued<Commodity>>

Grouping clause to extract input and output states into matched groups and then run a set of clauses over each group.

@@ -40,7 +40,7 @@ each group.

Issue -class Issue : AbstractIssue<State, Commodity>

Standard issue clause, specialised to match the commodity issue command.

+class Issue : AbstractIssue<State, Commands, Commodity>

Standard issue clause, specialised to match the commodity issue command.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-init-.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-init-.html index 3292d61c08..e7a7c96ac8 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-init-.html @@ -13,6 +13,10 @@ contract is intentionally similar to the Cash differences are in representation of the underlying commodity. Issuer in this context means the party who has the commodity, or is otherwise responsible for delivering the commodity on demand, and the deposit reference is use for internal accounting by the issuer (it might be, for example, a warehouse and/or location within a warehouse).

+

This is an early stage example contract used to illustrate non-cash fungible assets, and is likely to change significantly +in future.

+
+


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/exit-keys.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/exit-keys.html index dc1fbc4953..f627f790c0 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/exit-keys.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/exit-keys.html @@ -10,7 +10,8 @@ val exitKeys: MutableSet<PublicKey>
Overrides FungibleAsset.exitKeys
-

There must be an ExitCommand signed by these keys to destroy the amount

+

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/index.html index 5ca3c956ca..7bad2b4d99 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/-state/index.html @@ -51,7 +51,8 @@ is only intended for use by the issuer, and is not intended to be meaningful to exitKeys -val exitKeys: MutableSet<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount

+val exitKeys: MutableSet<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/conserve-clause.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/conserve-clause.html index c320721b6c..191cddd3b6 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/conserve-clause.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/conserve-clause.html @@ -8,7 +8,7 @@

conserveClause

-val conserveClause: AbstractConserveAmount<State, Commodity>
+val conserveClause: AbstractConserveAmount<State, Commands, Commodity>
Overrides OnLedgerAsset.conserveClause


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/extract-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/extract-commands.html index 3741430e8c..d19ba72999 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/extract-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/extract-commands.html @@ -7,8 +7,8 @@ com.r3corda.contracts.asset / CommodityContract / extractCommands

extractCommands

- -fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+ +fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
Overrides OnLedgerAsset.extractCommands


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/index.html index da38c50cf3..b1178646eb 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/index.html @@ -7,12 +7,16 @@ com.r3corda.contracts.asset / CommodityContract

CommodityContract

-class CommodityContract : OnLedgerAsset<Commodity, State>
+class CommodityContract : OnLedgerAsset<Commodity, Commands, State>

A commodity contract represents an amount of some commodity, tracked on a distributed ledger. The design of this contract is intentionally similar to the Cash contract, and the same commands (issue, move, exit) apply, the differences are in representation of the underlying commodity. Issuer in this context means the party who has the commodity, or is otherwise responsible for delivering the commodity on demand, and the deposit reference is use for internal accounting by the issuer (it might be, for example, a warehouse and/or location within a warehouse).

+

This is an early stage example contract used to illustrate non-cash fungible assets, and is likely to change significantly +in future.

+
+


Types

@@ -61,15 +65,9 @@ internal accounting by the issuer (it might be, for example, a warehouse and/or -clauses - -val clauses: <ERROR CLASS> - - - conserveClause -val conserveClause: AbstractConserveAmount<State, Commodity> +val conserveClause: AbstractConserveAmount<State, Commands, Commodity> @@ -96,7 +94,7 @@ when sending out "change" from spending/exiting.

extractCommands -fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>> +fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>> @@ -124,16 +122,11 @@ when sending out "change" from spending/exiting.

fun generateMoveCommand(): Move - - -

Inherited Functions

- - +verify + + + +
-verify -open fun verify(tx: TransactionForContract): 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.asset/-commodity-contract/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/verify.html new file mode 100644 index 0000000000..19cd56e2c4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-commodity-contract/verify.html @@ -0,0 +1,20 @@ + + +CommodityContract.verify - + + + +com.r3corda.contracts.asset / CommodityContract / 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.contracts.asset/-fungible-asset/-commands/-move.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/-commands/-move.html index 6747af2e99..22b9a5c8b8 100644 --- 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 @@ -47,6 +47,12 @@ order to settle an obligation contracts state object(s).

data class Move : Commands, Move

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

+Move +data class Move : Move, Commands
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/exit-keys.html b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/exit-keys.html index 920498dcfb..9e2bba4ae2 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/exit-keys.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-fungible-asset/exit-keys.html @@ -9,7 +9,8 @@

exitKeys

abstract val exitKeys: Collection<PublicKey>
-

There must be an ExitCommand signed by these keys to destroy the amount

+

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.



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 index 604557dd0c..26d54b8b9d 100644 --- 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 @@ -56,7 +56,8 @@ is only intended for use by the issuer, and is not intended to be meaningful to exitKeys -abstract val exitKeys: Collection<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount

+abstract val exitKeys: Collection<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-conserve-amount/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-conserve-amount/index.html index 8ccbe13554..4507fc93cc 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-conserve-amount/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-conserve-amount/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / ConserveAmount

ConserveAmount

-class ConserveAmount<P> : AbstractConserveAmount<State<P>, Terms<P>>
+class ConserveAmount<P> : AbstractConserveAmount<State<P>, Commands, Terms<P>>

Generic move/exit clause for fungible assets



@@ -23,29 +23,14 @@ -

Inherited Properties

+

Inherited Functions

+toString - - - - - - - - +open fun toString(): String
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-group/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-group/index.html index cb1f2931b9..3aa1e193e3 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-group/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-group/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / Group

Group

-class Group<P> : GroupClauseVerifier<State<P>, Issued<Terms<P>>>
+class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>

Parent clause for clauses that operate on grouped states (those which are fungible).



@@ -23,40 +23,14 @@ -

Properties

- - - - - - - - - - - - - - - -
-clauses -val clauses: <ERROR CLASS>
-ifMatched -val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-

Inherited Properties

+clause +val clause: Clause<S, C, K>
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
@@ -71,19 +45,5 @@ -

Inherited Functions

- - - - - - - -
-verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

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.

-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/index.html index b031c93cb8..9925328698 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / Issue

Issue

-class Issue<P> : AbstractIssue<State<P>, Terms<P>>
+class Issue<P> : AbstractIssue<State<P>, Commands, Terms<P>>

Generic issuance clause



@@ -30,7 +30,7 @@ requiredCommands -val requiredCommands: <ERROR CLASS>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -40,20 +40,6 @@ -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - sum val sum: List<S>.() -> Amount<Issued<T>> diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/required-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/required-commands.html index 4795724779..3f3ae5561a 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-issue/required-commands.html @@ -8,9 +8,9 @@

requiredCommands

-val requiredCommands: <ERROR CLASS>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/index.html index 9bd9b366cb..d31c359adc 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / Net

Net

-class Net<P> : NetClause<P>
+class Net<C : CommandData, P> : NetClause<C, P>

Clause for supporting netting of obligations.



@@ -23,40 +23,43 @@ +

Properties

+ + + + + + + +
+lifecycleClause +val lifecycleClause: VerifyLifecycle<ContractState, C, Unit, P>

Inherited Properties

- - - - - - - -
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

-

Inherited Functions

+

Functions

+toString + + + + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/lifecycle-clause.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/lifecycle-clause.html new file mode 100644 index 0000000000..efb6d0f599 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/lifecycle-clause.html @@ -0,0 +1,15 @@ + + +Obligation.Clauses.Net.lifecycleClause - + + + +com.r3corda.contracts.asset / Obligation / Clauses / Net / lifecycleClause
+
+

lifecycleClause

+ +val lifecycleClause: VerifyLifecycle<ContractState, C, Unit, P>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/to-string.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/to-string.html new file mode 100644 index 0000000000..8fe08b3cbf --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/to-string.html @@ -0,0 +1,15 @@ + + +Obligation.Clauses.Net.toString - + + + +com.r3corda.contracts.asset / Obligation / Clauses / Net / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/verify.html new file mode 100644 index 0000000000..3352737b1f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-net/verify.html @@ -0,0 +1,43 @@ + + +Obligation.Clauses.Net.verify - + + + +com.r3corda.contracts.asset / Obligation / Clauses / Net / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/index.html index 1bb5097161..eb1a3409c3 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / SetLifecycle

SetLifecycle

-class SetLifecycle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for changing the lifecycle of one or more states.



@@ -28,23 +28,9 @@ - - - - - - - - @@ -54,9 +40,18 @@ + + + + +fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms<P>>?): Set<Commands>

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.

+
-verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause +fun toString(): String

+verify +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>

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.

-ifMatched -val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
requiredCommands -val requiredCommands: <ERROR CLASS>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+toString +fun toString(): String
verify -fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData>
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/required-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/required-commands.html index df3a521777..e0d57bef06 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/required-commands.html @@ -8,9 +8,9 @@

requiredCommands

-val requiredCommands: <ERROR CLASS>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/to-string.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/to-string.html new file mode 100644 index 0000000000..8ae112d117 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/to-string.html @@ -0,0 +1,15 @@ + + +Obligation.Clauses.SetLifecycle.toString - + + + +com.r3corda.contracts.asset / Obligation / Clauses / SetLifecycle / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/verify.html index b363e0b85f..5fb2fa88cd 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-set-lifecycle/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts.asset / Obligation / Clauses / SetLifecycle / verify

verify

- -fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData>
+ +fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms<P>>?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/index.html index 4f53b31f4d..dd3245045f 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / Settle

Settle

-class Settle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for settling an outstanding obligation by witnessing change of ownership of other states to fulfil


@@ -30,23 +30,9 @@ change of ownership of other states to fulfil

-ifMatched - -val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - requiredCommands -val requiredCommands: <ERROR CLASS>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -58,7 +44,10 @@ change of ownership of other states to fulfil

verify -fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData> +fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms<P>>?): Set<Commands>

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.

+ diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/required-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/required-commands.html index e912df15c5..8062861903 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/required-commands.html @@ -8,9 +8,9 @@

requiredCommands

-val requiredCommands: <ERROR CLASS>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/verify.html index 02c7a66181..83140295a4 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-settle/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts.asset / Obligation / Clauses / Settle / verify

verify

- -fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData>
+ +fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms<P>>?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/index.html index 3c9cba12c5..ceb932aa78 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / Obligation / Clauses / VerifyLifecycle

VerifyLifecycle

-class VerifyLifecycle<P> : SingleClause, GroupClause<State<P>, Issued<Terms<P>>>
+class VerifyLifecycle<S : ContractState, C : CommandData, T : Any, P> : ConcreteClause<S, C, T>

Obligation-specific clause for verifying that all states are in normal lifecycle. In a group clause set, this must be run after any lifecycle change clause, which is the only clause that involve @@ -34,23 +34,9 @@ non-standard lifecycle states on input/output.

-ifMatched +requiredCommands -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - -requiredCommands - -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -62,11 +48,10 @@ non-standard lifecycle states on input/output.

verify -fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: T?): Set<C>

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.

-fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData>
-fun verify(inputs: List<State<P>>, outputs: List<State<P>>): Set<CommandData> + diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/verify.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/verify.html index 70dd795b86..9a631a9b89 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/-verify-lifecycle/verify.html @@ -7,12 +7,31 @@ com.r3corda.contracts.asset / Obligation / Clauses / VerifyLifecycle / verify

verify

- -fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>
-Overrides SingleVerify.verify
+ +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: T?): Set<C>

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

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 @@ -20,16 +39,5 @@ verify() functions may do further filtering on possible matches, and return a su commands that were not required (for example the Exit command for fungible assets is optional).



- -fun verify(tx: TransactionForContract, inputs: List<State<P>>, outputs: List<State<P>>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms<P>>): Set<CommandData>
-

Return
-the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

-
-
- -fun verify(inputs: List<State<P>>, outputs: List<State<P>>): Set<CommandData>
-
-
diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/index.html index fbc1f7662b..7b5feb64d9 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-clauses/index.html @@ -17,42 +17,42 @@ ConserveAmount -class ConserveAmount<P> : AbstractConserveAmount<State<P>, Terms<P>>

Generic move/exit clause for fungible assets

+class ConserveAmount<P> : AbstractConserveAmount<State<P>, Commands, Terms<P>>

Generic move/exit clause for fungible assets

Group -class Group<P> : GroupClauseVerifier<State<P>, Issued<Terms<P>>>

Parent clause for clauses that operate on grouped states (those which are fungible).

+class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>

Parent clause for clauses that operate on grouped states (those which are fungible).

Issue -class Issue<P> : AbstractIssue<State<P>, Terms<P>>

Generic issuance clause

+class Issue<P> : AbstractIssue<State<P>, Commands, Terms<P>>

Generic issuance clause

Net -class Net<P> : NetClause<P>

Clause for supporting netting of obligations.

+class Net<C : CommandData, P> : NetClause<C, P>

Clause for supporting netting of obligations.

SetLifecycle -class SetLifecycle<P> : GroupClause<State<P>, Issued<Terms<P>>>

Obligation-specific clause for changing the lifecycle of one or more states.

+class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for changing the lifecycle of one or more states.

Settle -class Settle<P> : GroupClause<State<P>, Issued<Terms<P>>>

Obligation-specific clause for settling an outstanding obligation by witnessing +class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for settling an outstanding obligation by witnessing change of ownership of other states to fulfil

@@ -60,7 +60,7 @@ change of ownership of other states to fulfil

VerifyLifecycle -class VerifyLifecycle<P> : SingleClause, GroupClause<State<P>, Issued<Terms<P>>>

Obligation-specific clause for verifying that all states are in +class VerifyLifecycle<S : ContractState, C : CommandData, T : Any, P> : ConcreteClause<S, C, T>

Obligation-specific clause for verifying that all states are in normal lifecycle. In a group clause set, this must be run after any lifecycle change clause, which is the only clause that involve non-standard lifecycle states on input/output.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/exit-keys.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/exit-keys.html index a78b27b3e8..75aa3d6605 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/exit-keys.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/-state/exit-keys.html @@ -10,9 +10,11 @@ val exitKeys: Collection<PublicKey>
Overrides FungibleAsset.exitKeys
-

There must be an ExitCommand signed by these keys to destroy the amount

+

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.

Getter
-

There must be an ExitCommand signed by these keys to destroy the amount

+

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.



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 index 18ce5d1269..03dfa75d22 100644 --- 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 @@ -79,7 +79,8 @@ is only intended for use by the issuer, and is not intended to be meaningful to exitKeys -val exitKeys: Collection<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount

+val exitKeys: Collection<PublicKey>

There must be an ExitCommand signed by these keys to destroy the amount. While all states require their +owner to sign, some (i.e. cash) also require the issuer.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-exit.html b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-exit.html index 2b0c6b4212..7b4a1d8fc5 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-exit.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/generate-exit.html @@ -7,8 +7,8 @@ com.r3corda.contracts.asset / Obligation / generateExit

generateExit

- -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, changeKey: PublicKey, assetStates: List<StateAndRef<State<P>>>): PublicKey
+ +fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, assetStates: List<StateAndRef<State<P>>>): PublicKey

Generate an transaction exiting an obligation from the ledger.

Parameters

@@ -17,10 +17,6 @@ amountIssued - the amount to be exited, represented as a quantity of issued currency.

- -changeKey - the key to send any change to. This needs to be explicitly stated as the input states are not -necessarily owned by us.
-
assetStates - the asset states to take funds from. No checks are done about ownership of these states, it is the responsibility of the caller to check that they do not exit funds held by others.
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 index 92827b3a48..384639a86e 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-obligation/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-obligation/index.html @@ -100,7 +100,7 @@ to be netted/merged, with settlement only for any remainder amount.

generateExit -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, changeKey: PublicKey, assetStates: List<StateAndRef<State<P>>>): PublicKey

Generate an transaction exiting an obligation from the ledger.

+fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, assetStates: List<StateAndRef<State<P>>>): PublicKey

Generate an transaction exiting an obligation from the ledger.

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/conserve-clause.html b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/conserve-clause.html index abcf9e108a..2c73b5bc55 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/conserve-clause.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/conserve-clause.html @@ -8,7 +8,7 @@

conserveClause

-abstract val conserveClause: AbstractConserveAmount<S, T>
+abstract val conserveClause: AbstractConserveAmount<S, C, T>


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/extract-commands.html b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/extract-commands.html index f38098f488..06de40373c 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/extract-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/extract-commands.html @@ -7,8 +7,8 @@ com.r3corda.contracts.asset / OnLedgerAsset / extractCommands

extractCommands

- -abstract fun extractCommands(tx: TransactionForContract): Collection<AuthenticatedObject<CommandData>>
+ +abstract fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): Collection<AuthenticatedObject<C>>


diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/generate-exit.html b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/generate-exit.html index 89fa7ec593..9790db56cb 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/generate-exit.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/generate-exit.html @@ -7,8 +7,8 @@ com.r3corda.contracts.asset / OnLedgerAsset / generateExit

generateExit

- -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, changeKey: PublicKey, assetStates: List<StateAndRef<S>>): PublicKey
+ +fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, assetStates: List<StateAndRef<S>>): PublicKey

Generate an transaction exiting assets from the ledger.

Parameters

diff --git a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/index.html b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/index.html index 27adbcea77..833536f4c1 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/-on-ledger-asset/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.asset / OnLedgerAsset

OnLedgerAsset

-abstract class OnLedgerAsset<T : Any, S : FungibleAsset<T>> : Contract
+abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : Contract

An asset transaction may split and merge assets 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 @@ -41,15 +41,9 @@ transaction.

-clauses - -abstract val clauses: List<SingleClause> - - - conserveClause -abstract val conserveClause: AbstractConserveAmount<S, T> +abstract val conserveClause: AbstractConserveAmount<S, C, T> @@ -82,13 +76,13 @@ when sending out "change" from spending/exiting.

extractCommands -abstract fun extractCommands(tx: TransactionForContract): Collection<AuthenticatedObject<CommandData>> +abstract fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): Collection<AuthenticatedObject<C>> generateExit -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, changeKey: PublicKey, assetStates: List<StateAndRef<S>>): PublicKey

Generate an transaction exiting assets from the ledger.

+fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, assetStates: List<StateAndRef<S>>): PublicKey

Generate an transaction exiting assets from the ledger.

@@ -117,11 +111,16 @@ when sending out "change" from spending/exiting.

Note that the wallet list is not updated: its up to you to do that.

+ + +

Inherited Functions

+ + +verify
-verify -open fun verify(tx: TransactionForContract): 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.

@@ -136,7 +135,7 @@ existing contract code.

Cash -class Cash : OnLedgerAsset<Currency, State>

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +class Cash : OnLedgerAsset<Currency, Commands, State>

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.

@@ -146,7 +145,7 @@ the same transaction.

CommodityContract -class CommodityContract : OnLedgerAsset<Commodity, State>

A commodity contract represents an amount of some commodity, tracked on a distributed ledger. The design of this +class CommodityContract : OnLedgerAsset<Commodity, Commands, State>

A commodity contract represents an amount of some commodity, tracked on a distributed ledger. The design of this contract is intentionally similar to the Cash contract, and the same commands (issue, move, exit) apply, the differences are in representation of the underlying commodity. Issuer in this context means the party who has the commodity, or is otherwise responsible for delivering the commodity on demand, and the deposit reference is use for diff --git a/docs/build/html/api/com.r3corda.contracts.asset/index.html b/docs/build/html/api/com.r3corda.contracts.asset/index.html index 20a3f8ea40..8bd796ad91 100644 --- a/docs/build/html/api/com.r3corda.contracts.asset/index.html +++ b/docs/build/html/api/com.r3corda.contracts.asset/index.html @@ -14,7 +14,7 @@

Cash -class Cash : OnLedgerAsset<Currency, State>

A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple +class Cash : OnLedgerAsset<Currency, Commands, State>

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.

@@ -24,7 +24,7 @@ the same transaction.

CommodityContract -class CommodityContract : OnLedgerAsset<Commodity, State>

A commodity contract represents an amount of some commodity, tracked on a distributed ledger. The design of this +class CommodityContract : OnLedgerAsset<Commodity, Commands, State>

A commodity contract represents an amount of some commodity, tracked on a distributed ledger. The design of this contract is intentionally similar to the Cash contract, and the same commands (issue, move, exit) apply, the differences are in representation of the underlying commodity. Issuer in this context means the party who has the commodity, or is otherwise responsible for delivering the commodity on demand, and the deposit reference is use for @@ -57,7 +57,7 @@ to be netted/merged, with settlement only for any remainder amount.

OnLedgerAsset -abstract class OnLedgerAsset<T : Any, S : FungibleAsset<T>> : Contract

An asset transaction may split and merge assets represented by a set of (issuer, depositRef) pairs, across multiple +abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : Contract

An asset transaction may split and merge assets 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.clause/-abstract-conserve-amount/generate-exit.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/generate-exit.html index efa2fa4686..35b588d54a 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/generate-exit.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/generate-exit.html @@ -7,8 +7,8 @@ com.r3corda.contracts.clause / AbstractConserveAmount / generateExit

generateExit

- -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, changeKey: PublicKey, assetStates: List<StateAndRef<S>>, deriveState: (TransactionState<S>, Amount<Issued<T>>, PublicKey) -> TransactionState<S>, generateExitCommand: (Amount<Issued<T>>) -> CommandData): PublicKey
+ +fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, assetStates: List<StateAndRef<S>>, deriveState: (TransactionState<S>, Amount<Issued<T>>, PublicKey) -> TransactionState<S>, generateExitCommand: (Amount<Issued<T>>) -> CommandData): PublicKey

Generate an transaction exiting fungible assets from the ledger.

Parameters

@@ -17,10 +17,6 @@ amountIssued - the amount to be exited, represented as a quantity of issued currency.

- -changeKey - the key to send any change to. This needs to be explicitly stated as the input states are not -necessarily owned by us.
-
assetStates - the asset states to take funds from. No checks are done about ownership of these states, it is the responsibility of the caller to check that they do not exit funds held by others.
diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/index.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/index.html index a0d69be2c2..07955c57e2 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/index.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.clause / AbstractConserveAmount

AbstractConserveAmount

-abstract class AbstractConserveAmount<S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standardised clause for checking input/output balances of fungible assets. Requires that a Move command is provided, and errors if absent. Must be the last clause under a grouping clause; errors on no-match, ends on match.

@@ -27,28 +27,14 @@ errors on no-match, ends on match.

-

Properties

+

Inherited Properties

+requiredCommands - - - - - - - - @@ -60,7 +46,7 @@ errors on no-match, ends on match.

@@ -73,9 +59,30 @@ Note that the wallet list is not updated: its up to you to do that.

+ + + + +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>

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.

+ + + +
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

generateExit -fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, changeKey: PublicKey, assetStates: List<StateAndRef<S>>, deriveState: (TransactionState<S>, Amount<Issued<T>>, PublicKey) -> TransactionState<S>, generateExitCommand: (Amount<Issued<T>>) -> CommandData): PublicKey

Generate an transaction exiting fungible assets from the ledger.

+fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<T>>, assetStates: List<StateAndRef<S>>, deriveState: (TransactionState<S>, Amount<Issued<T>>, PublicKey) -> TransactionState<S>, generateExitCommand: (Amount<Issued<T>>) -> CommandData): PublicKey

Generate an transaction exiting fungible assets from the ledger.

+toString +open fun toString(): String
verify -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+

Extension Functions

+ + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
@@ -86,20 +93,20 @@ Note that the wallet list is not updated: its up to you to do that.

ConserveAmount -class ConserveAmount : AbstractConserveAmount<State, Currency> +class ConserveAmount : AbstractConserveAmount<State, Commands, Currency> ConserveAmount -class ConserveAmount : AbstractConserveAmount<State, Commodity>

Standard clause for conserving the amount from input to output.

+class ConserveAmount : AbstractConserveAmount<State, Commands, Commodity>

Standard clause for conserving the amount from input to output.

ConserveAmount -class ConserveAmount<P> : AbstractConserveAmount<State<P>, Terms<P>>

Generic move/exit clause for fungible assets

+class ConserveAmount<P> : AbstractConserveAmount<State<P>, Commands, Terms<P>>

Generic move/exit clause for fungible assets

diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/to-string.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/to-string.html new file mode 100644 index 0000000000..43fe541caa --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/to-string.html @@ -0,0 +1,15 @@ + + +AbstractConserveAmount.toString - + + + +com.r3corda.contracts.clause / AbstractConserveAmount / toString
+
+

toString

+ +open fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/verify.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/verify.html index 35a983c610..ba1797c206 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-conserve-amount/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts.clause / AbstractConserveAmount / verify

verify

- -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+ +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/index.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/index.html index 90efe0a4ff..6bcc2db6fe 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.clause / AbstractIssue

AbstractIssue

-abstract class AbstractIssue<in S : ContractState, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standard issue clause for contracts that issue fungible assets.

Parameters

@@ -42,20 +42,6 @@ no states in the list. Takes in an instance of the token definition for construc -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - sum val sum: List<S>.() -> Amount<Issued<T>> @@ -68,6 +54,18 @@ no states in the list. Takes in an instance of the token definition for construc +

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+

Functions

@@ -75,7 +73,22 @@ no states in the list. Takes in an instance of the token definition for construc +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>

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.

+ + + +
verify -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+

Extension Functions

+ + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
@@ -86,27 +99,27 @@ no states in the list. Takes in an instance of the token definition for construc Issue -class Issue : AbstractIssue<State, Currency> +class Issue : AbstractIssue<State, Commands, Currency> Issue -class Issue : AbstractIssue<State, Commodity>

Standard issue clause, specialised to match the commodity issue command.

+class Issue : AbstractIssue<State, Commands, Commodity>

Standard issue clause, specialised to match the commodity issue command.

Issue -class Issue<P> : AbstractIssue<State<P>, Terms<P>>

Generic issuance clause

+class Issue<P> : AbstractIssue<State<P>, Commands, Terms<P>>

Generic issuance clause

Issue -class Issue : AbstractIssue<State, Terms> +class Issue : AbstractIssue<State, Commands, Terms> diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/verify.html b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/verify.html index 9f808ea829..f186b52a97 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-abstract-issue/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts.clause / AbstractIssue / verify

verify

- -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+ +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/index.html b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/index.html index f5137aa97a..6780ed381d 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/index.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.clause / NetClause

NetClause

-open class NetClause<P> : SingleClause
+open class NetClause<C : CommandData, P> : ConcreteClause<ContractState, C, Unit>

Clause for netting contract states. Currently only supports obligation contract.



@@ -28,23 +28,9 @@ -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -56,7 +42,7 @@ verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause +open fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>

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.

@@ -70,6 +56,18 @@ if any matched.

+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+

Inheritors

@@ -77,7 +75,7 @@ if any matched.

diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/required-commands.html b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/required-commands.html index d63f054481..6f0d40af2e 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/required-commands.html @@ -9,8 +9,8 @@

requiredCommands

open val requiredCommands: Set<Class<out CommandData>>
-Overrides SingleClause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/verify.html b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/verify.html index 7dec2db614..5288fb7b02 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-net-clause/verify.html @@ -7,12 +7,31 @@ com.r3corda.contracts.clause / NetClause / verify

verify

- -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>
-Overrides SingleVerify.verify
+ +open fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

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 diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/index.html b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/index.html index fbf824fce2..baaa15afcc 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/index.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts.clause / NoZeroSizedOutputs

NoZeroSizedOutputs

-open class NoZeroSizedOutputs<in S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Clause for fungible asset contracts, which enforces that no output state should have a balance of zero.


@@ -25,28 +25,14 @@ a balance of zero.

Net -class Net<P> : NetClause<P>

Clause for supporting netting of obligations.

+class Net<C : CommandData, P> : NetClause<C, P>

Clause for supporting netting of obligations.

-

Properties

+

Inherited Properties

+requiredCommands - - - - - - - - @@ -56,9 +42,30 @@ a balance of zero.

+ + + + +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>

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.

+ + + +
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-
-requiredCommands -open val requiredCommands: Set<Class<CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+toString +open fun toString(): String
verify -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+

Extension Functions

+ + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/to-string.html b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/to-string.html new file mode 100644 index 0000000000..424e3c3c50 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/to-string.html @@ -0,0 +1,15 @@ + + +NoZeroSizedOutputs.toString - + + + +com.r3corda.contracts.clause / NoZeroSizedOutputs / toString
+
+

toString

+ +open fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/verify.html b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/verify.html index 6ea4a1d922..afb384ce45 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/verify.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/-no-zero-sized-outputs/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts.clause / NoZeroSizedOutputs / verify

verify

- -open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<T>): Set<CommandData>
+ +open fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: Issued<T>?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts.clause/index.html b/docs/build/html/api/com.r3corda.contracts.clause/index.html index 99f331aff3..a70c20889e 100644 --- a/docs/build/html/api/com.r3corda.contracts.clause/index.html +++ b/docs/build/html/api/com.r3corda.contracts.clause/index.html @@ -14,7 +14,7 @@ AbstractConserveAmount -abstract class AbstractConserveAmount<S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>

Standardised clause for checking input/output balances of fungible assets. Requires that a +abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standardised clause for checking input/output balances of fungible assets. Requires that a Move command is provided, and errors if absent. Must be the last clause under a grouping clause; errors on no-match, ends on match.

@@ -23,7 +23,7 @@ errors on no-match, ends on match.

AbstractIssue -abstract class AbstractIssue<in S : ContractState, T : Any> : GroupClause<S, Issued<T>>

Standard issue clause for contracts that issue fungible assets.

+abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standard issue clause for contracts that issue fungible assets.

@@ -51,7 +51,7 @@ Used in cases where all parties (or their proxies) are signing, such as central NetClause -open class NetClause<P> : SingleClause

Clause for netting contract states. Currently only supports obligation contract.

+open class NetClause<C : CommandData, P> : ConcreteClause<ContractState, C, Unit>

Clause for netting contract states. Currently only supports obligation contract.

@@ -66,7 +66,7 @@ underlying issued thing.

NoZeroSizedOutputs -open class NoZeroSizedOutputs<in S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>

Clause for fungible asset contracts, which enforces that no output state should have +open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Clause for fungible asset contracts, which enforces that no output state should have a balance of zero.

diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/-init-.html index b802e81028..515d0420cf 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaperLegacy / Commands / Issue / <init>

<init>

-Issue(notary: Party)
+Issue()


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/index.html index 5c1cdb3712..8884b4c6fa 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaperLegacy / Commands / Issue

Issue

-data class Issue : Commands
+class Issue : TypeOnlyCommandData, Commands


Constructors

@@ -17,18 +17,24 @@ <init> -Issue(notary: Party) +Issue() -

Properties

+

Inherited Functions

+equals +open fun equals(other: Any?): Boolean + + + +
-notary -val notary: Party
+hashCode +open fun hashCode(): <ERROR CLASS>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/-init-.html index c746edfba9..2954058ffc 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaperLegacy / Commands / Redeem / <init>

<init>

-Redeem(notary: Party)
+Redeem()


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/index.html index c44449d2e4..1ed4019190 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/-redeem/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaperLegacy / Commands / Redeem

Redeem

-data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands


Constructors

@@ -17,18 +17,24 @@ <init> -Redeem(notary: Party) +Redeem() -

Properties

+

Inherited Functions

+equals +open fun equals(other: Any?): Boolean + + + +
-notary -val notary: Party
+hashCode +open fun hashCode(): <ERROR CLASS>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/index.html index 56e0800dc7..fbd0bdcc41 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-commands/index.html @@ -17,7 +17,7 @@ Issue -data class Issue : Commands +class Issue : TypeOnlyCommandData, Commands @@ -29,7 +29,7 @@ Redeem -data class Redeem : Commands +class Redeem : TypeOnlyCommandData, Commands @@ -40,7 +40,7 @@ Issue -data class Issue : Commands +class Issue : TypeOnlyCommandData, Commands @@ -52,7 +52,7 @@ Redeem -data class Redeem : Commands +class Redeem : TypeOnlyCommandData, Commands diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/index.html index c06f20e187..ff3af35a3c 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/index.html @@ -60,7 +60,7 @@ participants -val participants: List<PublicKey>

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

+val participants: <ERROR CLASS>

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.contracts/-commercial-paper-legacy/-state/participants.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/participants.html index e73e1b5056..ac2953666d 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/participants.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/-state/participants.html @@ -8,26 +8,17 @@

participants

-val participants: List<PublicKey>
+val participants: <ERROR CLASS>
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 +

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-legacy/generate-issue.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-issue.html new file mode 100644 index 0000000000..80002486c6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-issue.html @@ -0,0 +1,15 @@ + + +CommercialPaperLegacy.generateIssue - + + + +com.r3corda.contracts / CommercialPaperLegacy / generateIssue
+
+

generateIssue

+ +fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-move.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-move.html new file mode 100644 index 0000000000..63c5984706 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-move.html @@ -0,0 +1,15 @@ + + +CommercialPaperLegacy.generateMove - + + + +com.r3corda.contracts / CommercialPaperLegacy / generateMove
+
+

generateMove

+ +fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKey): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-redeem.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-redeem.html new file mode 100644 index 0000000000..cc24dfa6ea --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/generate-redeem.html @@ -0,0 +1,15 @@ + + +CommercialPaperLegacy.generateRedeem - + + + +com.r3corda.contracts / CommercialPaperLegacy / generateRedeem
+
+

generateRedeem

+ +fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: Wallet): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/index.html index 781a93dc9e..7e916f254d 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper-legacy/index.html @@ -56,6 +56,24 @@ the contracts contents).

+generateIssue + +fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder + + + +generateMove + +fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKey): Unit + + + +generateRedeem + +fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: Wallet): Unit + + + verify fun verify(tx: TransactionForContract): Unit

Takes an object that represents a state transition, and ensures the inputs/outputs/commands make sense. diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-group/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-group/index.html index 430423e449..46aff0e3fe 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-group/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-group/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Clauses / Group

Group

-class Group : GroupClauseVerifier<State, Issued<Terms>>
+class Group : GroupClauseVerifier<State, Commands, Issued<Terms>>


Constructors

@@ -21,40 +21,14 @@ -

Properties

- - - - - - - - - - - - - - - -
-clauses -val clauses: <ERROR CLASS>
-ifMatched -val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

-

Inherited Properties

+clause +val clause: Clause<S, C, K>
-requiredCommands -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

-
@@ -69,19 +43,5 @@ -

Inherited Functions

- - - - - - - -
-verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

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.

-
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/index.html index b420e7c48b..bdfe283a63 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Clauses / Issue

Issue

-class Issue : AbstractIssue<State, Terms>
+class Issue : AbstractIssue<State, Commands, Terms>


Constructors

@@ -28,7 +28,7 @@ requiredCommands -val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -38,20 +38,6 @@ -ifMatched - -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - sum val sum: List<S>.() -> Amount<Issued<T>> @@ -71,7 +57,10 @@ verify -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData> +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, token: Issued<Terms>?): Set<Commands>

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.

+ diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/required-commands.html index 3cb0370c70..1146aeae13 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/required-commands.html @@ -9,8 +9,8 @@

requiredCommands

val requiredCommands: Set<Class<out CommandData>>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/verify.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/verify.html index 3946184999..05b2524dbc 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/verify.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-issue/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts / CommercialPaper / Clauses / Issue / verify

verify

- -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData>
+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, token: Issued<Terms>?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/index.html index 0d471a9bd2..d9cbb14343 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Clauses / Move

Move

-class Move : AbstractGroupClause
+class Move : ConcreteClause<State, Commands, Issued<Terms>>


Constructors

@@ -28,26 +28,7 @@ requiredCommands -val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

- - - - -

Inherited Properties

- - - - - - - - - @@ -59,7 +40,10 @@ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms>?): Set<Commands>

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.

+
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

verify -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/required-commands.html index 206925ff0d..d95a9de2d5 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/required-commands.html @@ -9,8 +9,8 @@

requiredCommands

val requiredCommands: Set<Class<out CommandData>>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/verify.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/verify.html index 284b817bc1..366225a087 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/verify.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-move/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts / CommercialPaper / Clauses / Move / verify

verify

- -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData>
+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms>?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/index.html index fd364f02a5..9d70abed80 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Clauses / Redeem

Redeem

-class Redeem : AbstractGroupClause
+class Redeem : ConcreteClause<State, Commands, Issued<Terms>>


Constructors

@@ -28,26 +28,7 @@ requiredCommands -val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

- - - - -

Inherited Properties

- - - - - - - - - @@ -59,7 +40,10 @@ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms>?): Set<Commands>

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.

+
-ifMatched -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

-
-ifNotMatched -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

+val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

verify -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/required-commands.html index d1c35329e3..33d634c36c 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/required-commands.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/required-commands.html @@ -9,11 +9,8 @@

requiredCommands

val requiredCommands: Set<Class<out CommandData>>
-Overrides Clause.requiredCommands
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

-

Getter
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

-

+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/verify.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/verify.html index b9ff0f2b56..3ff25b3a6a 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/verify.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/-redeem/verify.html @@ -7,11 +7,36 @@ com.r3corda.contracts / CommercialPaper / Clauses / Redeem / verify

verify

- -fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: Collection<AuthenticatedObject<CommandData>>, token: Issued<Terms>): Set<CommandData>
+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Issued<Terms>?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

Return
the set of commands that are consumed IF this clause is matched, and cannot be used to match a -later clause.

+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).



diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/index.html index f950f1c567..f6f89d80db 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-clauses/index.html @@ -15,33 +15,27 @@ -AbstractGroupClause - -abstract class AbstractGroupClause : GroupClause<State, Issued<Terms>> - - - Group -class Group : GroupClauseVerifier<State, Issued<Terms>> +class Group : GroupClauseVerifier<State, Commands, Issued<Terms>> Issue -class Issue : AbstractIssue<State, Terms> +class Issue : AbstractIssue<State, Commands, Terms> Move -class Move : AbstractGroupClause +class Move : ConcreteClause<State, Commands, Issued<Terms>> Redeem -class Redeem : AbstractGroupClause +class Redeem : ConcreteClause<State, Commands, Issued<Terms>> diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/-init-.html index 21eea5007d..7593d3cfaa 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Commands / Issue / <init>

<init>

-Issue(notary: Party, nonce: Long = random63BitValue())
+Issue(nonce: Long = random63BitValue())


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/index.html index c4ad60508a..399de5c692 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-issue/index.html @@ -17,7 +17,7 @@ <init> -Issue(notary: Party, nonce: Long = random63BitValue()) +Issue(nonce: Long = random63BitValue()) @@ -30,12 +30,6 @@ val nonce: Long - - -notary - -val notary: Party - diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/-init-.html index 9c2cfd37cc..2a48069528 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Commands / Move / <init>

<init>

-Move()
+Move(contractHash: SecureHash? = null)


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/contract-hash.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/contract-hash.html new file mode 100644 index 0000000000..1c460a08c9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/contract-hash.html @@ -0,0 +1,18 @@ + + +CommercialPaper.Commands.Move.contractHash - + + + +com.r3corda.contracts / CommercialPaper / 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/-commercial-paper/-commands/-move/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/index.html index ebaf6c574c..7088c60abd 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-move/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Commands / Move

Move

-class Move : TypeOnlyCommandData, Commands
+data class Move : Move, Commands


Constructors

@@ -17,24 +17,20 @@ <init> -Move() +Move(contractHash: SecureHash? = null) -

Inherited Functions

+

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).

+
-equals -open fun equals(other: Any?): Boolean
-hashCode -open fun hashCode(): <ERROR CLASS>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/-init-.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/-init-.html index 586df05f26..0efbb441c3 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/-init-.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/-init-.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Commands / Redeem / <init>

<init>

-Redeem(notary: Party)
+Redeem()


diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/index.html index 46b4057217..c160fadc7e 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/-redeem/index.html @@ -7,7 +7,7 @@ com.r3corda.contracts / CommercialPaper / Commands / Redeem

Redeem

-data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands


Constructors

@@ -17,18 +17,24 @@ <init> -Redeem(notary: Party) +Redeem() -

Properties

+

Inherited Functions

+equals +open fun equals(other: Any?): Boolean + + + +
-notary -val notary: Party
+hashCode +open fun hashCode(): <ERROR CLASS>
diff --git a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/index.html b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/index.html index 45e6b48b9b..9652f3d433 100644 --- a/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/index.html +++ b/docs/build/html/api/com.r3corda.contracts/-commercial-paper/-commands/index.html @@ -23,13 +23,13 @@ Move -class Move : TypeOnlyCommandData, Commands +data class Move : Move, Commands Redeem -data class Redeem : Commands +class Redeem : TypeOnlyCommandData, Commands @@ -46,13 +46,13 @@ Move -class Move : TypeOnlyCommandData, Commands +data class Move : Move, Commands Redeem -data class Redeem : Commands +class Redeem : TypeOnlyCommandData, Commands diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/-init-.html new file mode 100644 index 0000000000..5a2c08aece --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/-init-.html @@ -0,0 +1,16 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / <init>
+
+

<init>

+AbstractIRSClause()
+

Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides +helper functions for the clauses.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-amounts.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-amounts.html new file mode 100644 index 0000000000..0ced916de5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-amounts.html @@ -0,0 +1,15 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.checkLegAmounts - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / checkLegAmounts
+
+

checkLegAmounts

+ +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-dates.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-dates.html new file mode 100644 index 0000000000..a2247f4714 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-leg-dates.html @@ -0,0 +1,15 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.checkLegDates - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / checkLegDates
+
+

checkLegDates

+ +fun checkLegDates(legs: List<CommonLeg>): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-rates.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-rates.html new file mode 100644 index 0000000000..cb2bbce6f4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-rates.html @@ -0,0 +1,15 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.checkRates - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / checkRates
+
+

checkRates

+ +fun checkRates(legs: List<CommonLeg>): Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-schedules.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-schedules.html new file mode 100644 index 0000000000..c49d51b695 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/check-schedules.html @@ -0,0 +1,15 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.checkSchedules - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / checkSchedules
+
+

checkSchedules

+ +fun checkSchedules(legs: List<CommonLeg>): Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/get-floating-leg-payments-differences.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/get-floating-leg-payments-differences.html new file mode 100644 index 0000000000..cc39d4fab9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/get-floating-leg-payments-differences.html @@ -0,0 +1,16 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause.getFloatingLegPaymentsDifferences - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause / getFloatingLegPaymentsDifferences
+
+

getFloatingLegPaymentsDifferences

+ +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>
+

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/index.html new file mode 100644 index 0000000000..b176f43a24 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-abstract-i-r-s-clause/index.html @@ -0,0 +1,106 @@ + + +InterestRateSwap.Clauses.AbstractIRSClause - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / AbstractIRSClause
+
+

AbstractIRSClause

+abstract class AbstractIRSClause : ConcreteClause<State, Commands, UniqueIdentifier>
+

Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides +helper functions for the clauses.

+
+
+

Constructors

+ + + + + + + +
+<init> +AbstractIRSClause()

Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides +helper functions for the clauses.

+
+

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + + + + + + + + + + + + + + + + + +
+checkLegAmounts +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+checkLegDates +fun checkLegDates(legs: List<CommonLeg>): Unit
+checkRates +fun checkRates(legs: List<CommonLeg>): Boolean
+checkSchedules +fun checkSchedules(legs: List<CommonLeg>): Boolean
+getFloatingLegPaymentsDifferences +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+

Inheritors

+ + + + + + + + + + + + + + + + + + + +
+Agree +class Agree : AbstractIRSClause
+Fix +class Fix : AbstractIRSClause
+Mature +class Mature : AbstractIRSClause
+Pay +class Pay : AbstractIRSClause
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/-init-.html new file mode 100644 index 0000000000..eaf0f23696 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Agree.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Agree / <init>
+
+

<init>

+Agree()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/index.html new file mode 100644 index 0000000000..a72bee585b --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/index.html @@ -0,0 +1,87 @@ + + +InterestRateSwap.Clauses.Agree - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Agree
+
+

Agree

+class Agree : AbstractIRSClause
+
+
+

Constructors

+ + + + + + + +
+<init> +Agree()
+

Properties

+ + + + + + + +
+requiredCommands +val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+verify +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>

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.

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + +
+checkLegAmounts +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+checkLegDates +fun checkLegDates(legs: List<CommonLeg>): Unit
+checkRates +fun checkRates(legs: List<CommonLeg>): Boolean
+checkSchedules +fun checkSchedules(legs: List<CommonLeg>): Boolean
+getFloatingLegPaymentsDifferences +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/required-commands.html new file mode 100644 index 0000000000..00ee067c9f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/required-commands.html @@ -0,0 +1,17 @@ + + +InterestRateSwap.Clauses.Agree.requiredCommands - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Agree / requiredCommands
+
+

requiredCommands

+ +val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/verify.html new file mode 100644 index 0000000000..01aef25449 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-agree/verify.html @@ -0,0 +1,43 @@ + + +InterestRateSwap.Clauses.Agree.verify - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Agree / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/-init-.html new file mode 100644 index 0000000000..f136836a8f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Fix.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Fix / <init>
+
+

<init>

+Fix()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/index.html new file mode 100644 index 0000000000..5965258bc3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/index.html @@ -0,0 +1,87 @@ + + +InterestRateSwap.Clauses.Fix - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Fix
+
+

Fix

+class Fix : AbstractIRSClause
+
+
+

Constructors

+ + + + + + + +
+<init> +Fix()
+

Properties

+ + + + + + + +
+requiredCommands +val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+verify +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>

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.

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + +
+checkLegAmounts +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+checkLegDates +fun checkLegDates(legs: List<CommonLeg>): Unit
+checkRates +fun checkRates(legs: List<CommonLeg>): Boolean
+checkSchedules +fun checkSchedules(legs: List<CommonLeg>): Boolean
+getFloatingLegPaymentsDifferences +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/required-commands.html new file mode 100644 index 0000000000..6daf5fc146 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/required-commands.html @@ -0,0 +1,17 @@ + + +InterestRateSwap.Clauses.Fix.requiredCommands - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Fix / requiredCommands
+
+

requiredCommands

+ +val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/verify.html new file mode 100644 index 0000000000..bf4c0df6f4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-fix/verify.html @@ -0,0 +1,43 @@ + + +InterestRateSwap.Clauses.Fix.verify - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Fix / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/-init-.html new file mode 100644 index 0000000000..337ea3cd72 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Group.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Group / <init>
+
+

<init>

+Group()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/group-states.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/group-states.html new file mode 100644 index 0000000000..5d6f493463 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/group-states.html @@ -0,0 +1,16 @@ + + +InterestRateSwap.Clauses.Group.groupStates - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Group / groupStates
+
+

groupStates

+ +fun groupStates(tx: TransactionForContract): List<InOutGroup<State, UniqueIdentifier>>
+Overrides GroupClauseVerifier.groupStates
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/index.html new file mode 100644 index 0000000000..d030ab03ed --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-group/index.html @@ -0,0 +1,47 @@ + + +InterestRateSwap.Clauses.Group - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Group
+
+

Group

+class Group : GroupClauseVerifier<State, Commands, UniqueIdentifier>
+
+
+

Constructors

+ + + + + + + +
+<init> +Group()
+

Inherited Properties

+ + + + + + + +
+clause +val clause: Clause<S, C, K>
+

Functions

+ + + + + + + +
+groupStates +fun groupStates(tx: TransactionForContract): List<InOutGroup<State, UniqueIdentifier>>
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/-init-.html new file mode 100644 index 0000000000..0114e14a79 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Mature.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Mature / <init>
+
+

<init>

+Mature()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/index.html new file mode 100644 index 0000000000..7527e431c9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/index.html @@ -0,0 +1,87 @@ + + +InterestRateSwap.Clauses.Mature - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Mature
+
+

Mature

+class Mature : AbstractIRSClause
+
+
+

Constructors

+ + + + + + + +
+<init> +Mature()
+

Properties

+ + + + + + + +
+requiredCommands +val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+verify +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>

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.

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + +
+checkLegAmounts +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+checkLegDates +fun checkLegDates(legs: List<CommonLeg>): Unit
+checkRates +fun checkRates(legs: List<CommonLeg>): Boolean
+checkSchedules +fun checkSchedules(legs: List<CommonLeg>): Boolean
+getFloatingLegPaymentsDifferences +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/required-commands.html new file mode 100644 index 0000000000..7c50ebe133 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/required-commands.html @@ -0,0 +1,17 @@ + + +InterestRateSwap.Clauses.Mature.requiredCommands - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Mature / requiredCommands
+
+

requiredCommands

+ +val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/verify.html new file mode 100644 index 0000000000..6ce4a835ae --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-mature/verify.html @@ -0,0 +1,43 @@ + + +InterestRateSwap.Clauses.Mature.verify - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Mature / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/-init-.html new file mode 100644 index 0000000000..6855d96d28 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Pay.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Pay / <init>
+
+

<init>

+Pay()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/index.html new file mode 100644 index 0000000000..5f3cf3b48f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/index.html @@ -0,0 +1,87 @@ + + +InterestRateSwap.Clauses.Pay - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Pay
+
+

Pay

+class Pay : AbstractIRSClause
+
+
+

Constructors

+ + + + + + + +
+<init> +Pay()
+

Properties

+ + + + + + + +
+requiredCommands +val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+verify +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>

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.

+
+

Inherited Functions

+ + + + + + + + + + + + + + + + + + + + + + + +
+checkLegAmounts +fun checkLegAmounts(legs: List<CommonLeg>): Unit
+checkLegDates +fun checkLegDates(legs: List<CommonLeg>): Unit
+checkRates +fun checkRates(legs: List<CommonLeg>): Boolean
+checkSchedules +fun checkSchedules(legs: List<CommonLeg>): Boolean
+getFloatingLegPaymentsDifferences +fun getFloatingLegPaymentsDifferences(payments1: Map<LocalDate, Event>, payments2: Map<LocalDate, Event>): List<<ERROR CLASS><LocalDate, <ERROR CLASS><FloatingRatePaymentEvent, FloatingRatePaymentEvent>>>

Compares two schedules of Floating Leg Payments, returns the difference (i.e. omissions in either leg or changes to the values).

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/required-commands.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/required-commands.html new file mode 100644 index 0000000000..4d947248d1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/required-commands.html @@ -0,0 +1,17 @@ + + +InterestRateSwap.Clauses.Pay.requiredCommands - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Pay / requiredCommands
+
+

requiredCommands

+ +val requiredCommands: Set<Class<out CommandData>>
+Overrides ConcreteClause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/verify.html new file mode 100644 index 0000000000..492ec6661f --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-pay/verify.html @@ -0,0 +1,43 @@ + + +InterestRateSwap.Clauses.Pay.verify - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Pay / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<State>, outputs: List<State>, commands: List<AuthenticatedObject<Commands>>, groupingKey: UniqueIdentifier?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/-init-.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/-init-.html new file mode 100644 index 0000000000..e5d663e0a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/-init-.html @@ -0,0 +1,14 @@ + + +InterestRateSwap.Clauses.Timestamped.<init> - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Timestamped / <init>
+
+

<init>

+Timestamped()
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/index.html new file mode 100644 index 0000000000..7969b594fc --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/index.html @@ -0,0 +1,51 @@ + + +InterestRateSwap.Clauses.Timestamped - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Timestamped
+
+

Timestamped

+class Timestamped : ConcreteClause<ContractState, Commands, Unit>
+
+
+

Constructors

+ + + + + + + +
+<init> +Timestamped()
+

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+verify +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Unit?): Set<Commands>

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.

+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/verify.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/verify.html new file mode 100644 index 0000000000..0f672621e4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/-timestamped/verify.html @@ -0,0 +1,43 @@ + + +InterestRateSwap.Clauses.Timestamped.verify - + + + +com.r3corda.contracts / InterestRateSwap / Clauses / Timestamped / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<Commands>>, groupingKey: Unit?): Set<Commands>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/index.html b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/index.html new file mode 100644 index 0000000000..59ecd08969 --- /dev/null +++ b/docs/build/html/api/com.r3corda.contracts/-interest-rate-swap/-clauses/index.html @@ -0,0 +1,63 @@ + + +InterestRateSwap.Clauses - + + + +com.r3corda.contracts / InterestRateSwap / Clauses
+
+

Clauses

+interface Clauses
+
+
+

Types

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+AbstractIRSClause +abstract class AbstractIRSClause : ConcreteClause<State, Commands, UniqueIdentifier>

Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides +helper functions for the clauses.

+
+Agree +class Agree : AbstractIRSClause
+Fix +class Fix : AbstractIRSClause
+Group +class Group : GroupClauseVerifier<State, Commands, UniqueIdentifier>
+Mature +class Mature : AbstractIRSClause
+Pay +class Pay : AbstractIRSClause
+Timestamped +class Timestamped : ConcreteClause<ContractState, Commands, Unit>
+ + 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 f21ebdba0a..421ff2e28c 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 @@ -29,9 +29,9 @@ copy / update for each transition).

-Clause +Clauses -interface Clause +interface Clauses @@ -107,12 +107,6 @@ the contracts contents).

-extractCommands - -fun extractCommands(tx: TransactionForContract): Collection<AuthenticatedObject<CommandData>> - - - generateAgreement fun generateAgreement(floatingLeg: FloatingLeg, fixedLeg: FixedLeg, calculation: Calculation, common: Common, notary: Party): TransactionBuilder

This generates the agreement state and also the schedules from the initial data. diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/-init-.html new file mode 100644 index 0000000000..018c20ddf8 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/-init-.html @@ -0,0 +1,15 @@ + + +AllComposition.<init> - + + + +com.r3corda.core.contracts.clauses / AllComposition / <init>
+
+

<init>

+AllComposition(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>)
+

Compose a number of clauses, such that all of the clauses must run for verification to pass.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/clauses.html new file mode 100644 index 0000000000..4e502cbe75 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/clauses.html @@ -0,0 +1,17 @@ + + +AllComposition.clauses - + + + +com.r3corda.core.contracts.clauses / AllComposition / clauses
+
+

clauses

+ +val clauses: ArrayList<Clause<S, C, K>>
+Overrides CompositeClause.clauses
+

List of clauses under this composite clause

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/index.html new file mode 100644 index 0000000000..73d8b93a91 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/index.html @@ -0,0 +1,90 @@ + + +AllComposition - + + + +com.r3corda.core.contracts.clauses / AllComposition
+
+

AllComposition

+class AllComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
+

Compose a number of clauses, such that all of the clauses must run for verification to pass.

+
+
+

Constructors

+ + + + + + + +
+<init> +AllComposition(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>)

Compose a number of clauses, such that all of the clauses must run for verification to pass.

+
+

Properties

+ + + + + + + +
+clauses +val clauses: ArrayList<Clause<S, C, K>>

List of clauses under this composite clause

+
+

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + + + + + + + + + +
+matchedClauses +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>

Determine which clauses are matched by the supplied commands

+
+toString +fun toString(): String
+verify +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>

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.

+
+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/matched-clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/matched-clauses.html new file mode 100644 index 0000000000..f432bc4069 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/matched-clauses.html @@ -0,0 +1,16 @@ + + +AllComposition.matchedClauses - + + + +com.r3corda.core.contracts.clauses / AllComposition / matchedClauses
+
+

matchedClauses

+ +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>
+

Determine which clauses are matched by the supplied commands

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/to-string.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/to-string.html new file mode 100644 index 0000000000..5007ead7e9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/to-string.html @@ -0,0 +1,15 @@ + + +AllComposition.toString - + + + +com.r3corda.core.contracts.clauses / AllComposition / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/verify.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/verify.html new file mode 100644 index 0000000000..1b97d1936b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-all-composition/verify.html @@ -0,0 +1,43 @@ + + +AllComposition.verify - + + + +com.r3corda.core.contracts.clauses / AllComposition / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/-init-.html new file mode 100644 index 0000000000..5c2661bda3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/-init-.html @@ -0,0 +1,15 @@ + + +AnyComposition.<init> - + + + +com.r3corda.core.contracts.clauses / AnyComposition / <init>
+
+

<init>

+AnyComposition(vararg rawClauses: Clause<S, C, K>)
+

Compose a number of clauses, such that any number of the clauses can run.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/clauses.html new file mode 100644 index 0000000000..2e7e0d72e2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/clauses.html @@ -0,0 +1,17 @@ + + +AnyComposition.clauses - + + + +com.r3corda.core.contracts.clauses / AnyComposition / clauses
+
+

clauses

+ +val clauses: List<Clause<S, C, K>>
+Overrides CompositeClause.clauses
+

List of clauses under this composite clause

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/index.html new file mode 100644 index 0000000000..f1de7e789d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/index.html @@ -0,0 +1,96 @@ + + +AnyComposition - + + + +com.r3corda.core.contracts.clauses / AnyComposition
+
+

AnyComposition

+class AnyComposition<in S : ContractState, C : CommandData, in K : Any> : CompositeClause<S, C, K>
+

Compose a number of clauses, such that any number of the clauses can run.

+
+
+

Constructors

+ + + + + + + +
+<init> +AnyComposition(vararg rawClauses: Clause<S, C, K>)

Compose a number of clauses, such that any number of the clauses can run.

+
+

Properties

+ + + + + + + + + + + +
+clauses +val clauses: List<Clause<S, C, K>>

List of clauses under this composite clause

+
+rawClauses +vararg val rawClauses: Array<out Clause<S, C, K>>
+

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + + + + + + + + + +
+matchedClauses +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>

Determine which clauses are matched by the supplied commands

+
+toString +fun toString(): String
+verify +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>

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.

+
+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/matched-clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/matched-clauses.html new file mode 100644 index 0000000000..41637fa8bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/matched-clauses.html @@ -0,0 +1,16 @@ + + +AnyComposition.matchedClauses - + + + +com.r3corda.core.contracts.clauses / AnyComposition / matchedClauses
+
+

matchedClauses

+ +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>
+

Determine which clauses are matched by the supplied commands

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/raw-clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/raw-clauses.html new file mode 100644 index 0000000000..6c22639ddb --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/raw-clauses.html @@ -0,0 +1,15 @@ + + +AnyComposition.rawClauses - + + + +com.r3corda.core.contracts.clauses / AnyComposition / rawClauses
+
+

rawClauses

+ +vararg val rawClauses: Array<out Clause<S, C, K>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/to-string.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/to-string.html new file mode 100644 index 0000000000..c3da17d05c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/to-string.html @@ -0,0 +1,15 @@ + + +AnyComposition.toString - + + + +com.r3corda.core.contracts.clauses / AnyComposition / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/verify.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/verify.html new file mode 100644 index 0000000000..d4a1f3e6c9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-any-composition/verify.html @@ -0,0 +1,43 @@ + + +AnyComposition.verify - + + + +com.r3corda.core.contracts.clauses / AnyComposition / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/get-execution-path.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/get-execution-path.html new file mode 100644 index 0000000000..9f5cfbff94 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/get-execution-path.html @@ -0,0 +1,16 @@ + + +Clause.getExecutionPath - + + + +com.r3corda.core.contracts.clauses / Clause / getExecutionPath
+
+

getExecutionPath

+ +abstract fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
+

Determine the subclauses which will be verified as a result of verifying this clause.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/index.html index 2a52648752..64369a2de7 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/index.html @@ -7,8 +7,16 @@ com.r3corda.core.contracts.clauses / Clause

Clause

-interface Clause
-

A clause that can be matched as part of execution of a contract.

+interface Clause<in S : ContractState, C : CommandData, in K : Any>
+

Parameters

+ +S - the type of contract state this clause operates on.
+
+ +C - a common supertype of commands this clause operates on.
+
+ +K - the type of the grouping key for states this clause operates on. Use Unit if not applicable.


Properties

@@ -16,23 +24,53 @@ -ifMatched - -abstract val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -abstract val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - requiredCommands -abstract val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+abstract val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+ + + + +

Functions

+ + + + + + + + + + + +
+getExecutionPath +abstract fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>

Determine the subclauses which will be verified as a result of verifying this clause.

+
+verify +abstract fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>

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.

+
+

Companion Object Properties

+ + + + + + + +
+log +val log: <ERROR CLASS>
+

Extension Functions

+ + + + + @@ -42,16 +80,17 @@ +CompositeClause +abstract class CompositeClause<in S : ContractState, C : CommandData, in K : Any> : Clause<S, C, K>

Abstract supertype for clauses which compose other clauses together in some logical manner.

+ +ConcreteClause diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/log.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/log.html new file mode 100644 index 0000000000..5541d6e924 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/log.html @@ -0,0 +1,15 @@ + + +Clause.log - + + + +com.r3corda.core.contracts.clauses / Clause / log
+
+

log

+ +val log: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/required-commands.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/required-commands.html index 52bd29135a..460b9b0317 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/required-commands.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/required-commands.html @@ -9,7 +9,7 @@

requiredCommands

abstract val requiredCommands: Set<Class<out CommandData>>
-

Classes for commands which must ALL be present in transaction for this clause to be triggered

+

Determine whether this clause runs or not



diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/verify.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/verify.html new file mode 100644 index 0000000000..e717d9471e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-clause/verify.html @@ -0,0 +1,43 @@ + + +Clause.verify - + + + +com.r3corda.core.contracts.clauses / Clause / verify
+
+

verify

+ +abstract fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/-init-.html new file mode 100644 index 0000000000..9feff0501b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/-init-.html @@ -0,0 +1,18 @@ + + +CompositeClause.<init> - + + + +com.r3corda.core.contracts.clauses / CompositeClause / <init>
+
+

<init>

+CompositeClause()
+

Abstract supertype for clauses which compose other clauses together in some logical manner.

+

See Also
+

ConcreteClause

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/clauses.html new file mode 100644 index 0000000000..58aa6534aa --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/clauses.html @@ -0,0 +1,16 @@ + + +CompositeClause.clauses - + + + +com.r3corda.core.contracts.clauses / CompositeClause / clauses
+
+

clauses

+ +abstract val clauses: List<Clause<S, C, K>>
+

List of clauses under this composite clause

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/get-execution-path.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/get-execution-path.html new file mode 100644 index 0000000000..f7a3b6e8ab --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/get-execution-path.html @@ -0,0 +1,16 @@ + + +CompositeClause.getExecutionPath - + + + +com.r3corda.core.contracts.clauses / CompositeClause / getExecutionPath
+
+

getExecutionPath

+ +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
+

Determine the subclauses which will be verified as a result of verifying this clause.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/index.html new file mode 100644 index 0000000000..d6fe3c9d05 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/index.html @@ -0,0 +1,106 @@ + + +CompositeClause - + + + +com.r3corda.core.contracts.clauses / CompositeClause
+
+

CompositeClause

+abstract class CompositeClause<in S : ContractState, C : CommandData, in K : Any> : Clause<S, C, K>
+

Abstract supertype for clauses which compose other clauses together in some logical manner.

+

See Also
+

ConcreteClause

+

+
+
+

Constructors

+
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

-GroupClause -interface GroupClause<in S : ContractState, in T : Any> : Clause, GroupVerify<S, T>
-SingleClause -abstract class SingleClause : Clause, SingleVerify

A single verifiable clause. By default always matches, continues to the next clause when matched and errors -if not matched.

+abstract class ConcreteClause<in S : ContractState, C : CommandData, in T : Any> : Clause<S, C, T>

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+ + + + + + +
+<init> +CompositeClause()

Abstract supertype for clauses which compose other clauses together in some logical manner.

+
+

Properties

+ + + + + + + + + + + +
+clauses +abstract val clauses: List<Clause<S, C, K>>

List of clauses under this composite clause

+
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + + + + + +
+getExecutionPath +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>

Determine the subclauses which will be verified as a result of verifying this clause.

+
+matchedClauses +abstract fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>

Determine which clauses are matched by the supplied commands

+
+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+

Inheritors

+ + + + + + + + + + + + + + + +
+AllComposition +class AllComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that all of the clauses must run for verification to pass.

+
+AnyComposition +class AnyComposition<in S : ContractState, C : CommandData, in K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that any number of the clauses can run.

+
+FirstComposition +class FirstComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/matched-clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/matched-clauses.html new file mode 100644 index 0000000000..b38a34951e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/matched-clauses.html @@ -0,0 +1,16 @@ + + +CompositeClause.matchedClauses - + + + +com.r3corda.core.contracts.clauses / CompositeClause / matchedClauses
+
+

matchedClauses

+ +abstract fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>
+

Determine which clauses are matched by the supplied commands

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/required-commands.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/required-commands.html new file mode 100644 index 0000000000..d8f05c9050 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-composite-clause/required-commands.html @@ -0,0 +1,17 @@ + + +CompositeClause.requiredCommands - + + + +com.r3corda.core.contracts.clauses / CompositeClause / requiredCommands
+
+

requiredCommands

+ +open val requiredCommands: Set<Class<out CommandData>>
+Overrides Clause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/-init-.html new file mode 100644 index 0000000000..7742bffcf7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/-init-.html @@ -0,0 +1,19 @@ + + +ConcreteClause.<init> - + + + +com.r3corda.core.contracts.clauses / ConcreteClause / <init>
+
+

<init>

+ConcreteClause()
+

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+

See Also
+

CompositeClause

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/get-execution-path.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/get-execution-path.html new file mode 100644 index 0000000000..dc88575ee5 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/get-execution-path.html @@ -0,0 +1,16 @@ + + +ConcreteClause.getExecutionPath - + + + +com.r3corda.core.contracts.clauses / ConcreteClause / getExecutionPath
+
+

getExecutionPath

+ +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
+

Determine the subclauses which will be verified as a result of verifying this clause.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/index.html new file mode 100644 index 0000000000..d09f2ab208 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/index.html @@ -0,0 +1,168 @@ + + +ConcreteClause - + + + +com.r3corda.core.contracts.clauses / ConcreteClause
+
+

ConcreteClause

+abstract class ConcreteClause<in S : ContractState, C : CommandData, in T : Any> : Clause<S, C, T>
+

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+

See Also
+

CompositeClause

+

+
+
+

Constructors

+ + + + + + + +
+<init> +ConcreteClause()

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+
+

Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + +
+getExecutionPath +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>

Determine the subclauses which will be verified as a result of verifying this clause.

+
+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+

Inheritors

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+AbstractConserveAmount +abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standardised clause for checking input/output balances of fungible assets. Requires that a +Move command is provided, and errors if absent. Must be the last clause under a grouping clause; +errors on no-match, ends on match.

+
+AbstractIRSClause +abstract class AbstractIRSClause : ConcreteClause<State, Commands, UniqueIdentifier>

Common superclass for IRS contract clauses, which defines behaviour on match/no-match, and provides +helper functions for the clauses.

+
+AbstractIssue +abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Standard issue clause for contracts that issue fungible assets.

+
+ClauseVerifier +class ClauseVerifier<S : LinearState> : ConcreteClause<ContractState, CommandData, Unit>

Standard clause to verify the LinearState safety properties.

+
+GroupClauseVerifier +abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any> : ConcreteClause<ContractState, C, Unit>
+Move +class Move : ConcreteClause<State, Commands, Issued<Terms>>
+NetClause +open class NetClause<C : CommandData, P> : ConcreteClause<ContractState, C, Unit>

Clause for netting contract states. Currently only supports obligation contract.

+
+NoZeroSizedOutputs +open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

Clause for fungible asset contracts, which enforces that no output state should have +a balance of zero.

+
+Redeem +class Redeem : ConcreteClause<State, Commands, Issued<Terms>>
+SetLifecycle +class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for changing the lifecycle of one or more states.

+
+Settle +class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>

Obligation-specific clause for settling an outstanding obligation by witnessing +change of ownership of other states to fulfil

+
+Timestamped +class Timestamped : ConcreteClause<ContractState, Commands, Unit>
+VerifyLifecycle +class VerifyLifecycle<S : ContractState, C : CommandData, T : Any, P> : ConcreteClause<S, C, T>

Obligation-specific clause for verifying that all states are in +normal lifecycle. In a group clause set, this must be run after +any lifecycle change clause, which is the only clause that involve +non-standard lifecycle states on input/output.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/required-commands.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/required-commands.html new file mode 100644 index 0000000000..c8977a4f24 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-concrete-clause/required-commands.html @@ -0,0 +1,17 @@ + + +ConcreteClause.requiredCommands - + + + +com.r3corda.core.contracts.clauses / ConcreteClause / requiredCommands
+
+

requiredCommands

+ +open val requiredCommands: Set<Class<out CommandData>>
+Overrides Clause.requiredCommands
+

Determine whether this clause runs or not

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/-init-.html new file mode 100644 index 0000000000..8f7b3ea94c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/-init-.html @@ -0,0 +1,15 @@ + + +FirstComposition.<init> - + + + +com.r3corda.core.contracts.clauses / FirstComposition / <init>
+
+

<init>

+FirstComposition(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>)
+

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/clauses.html new file mode 100644 index 0000000000..e37291e7cc --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/clauses.html @@ -0,0 +1,17 @@ + + +FirstComposition.clauses - + + + +com.r3corda.core.contracts.clauses / FirstComposition / clauses
+
+

clauses

+ +val clauses: ArrayList<Clause<S, C, K>>
+Overrides CompositeClause.clauses
+

List of clauses under this composite clause

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/first-clause.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/first-clause.html new file mode 100644 index 0000000000..737d4fee4e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/first-clause.html @@ -0,0 +1,15 @@ + + +FirstComposition.firstClause - + + + +com.r3corda.core.contracts.clauses / FirstComposition / firstClause
+
+

firstClause

+ +val firstClause: Clause<S, C, K>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/index.html new file mode 100644 index 0000000000..077114fb88 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/index.html @@ -0,0 +1,107 @@ + + +FirstComposition - + + + +com.r3corda.core.contracts.clauses / FirstComposition
+
+

FirstComposition

+class FirstComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
+

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+
+
+

Constructors

+ + + + + + + +
+<init> +FirstComposition(firstClause: Clause<S, C, K>, vararg remainingClauses: Clause<S, C, K>)

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+
+

Properties

+ + + + + + + + + + + +
+clauses +val clauses: ArrayList<Clause<S, C, K>>

List of clauses under this composite clause

+
+firstClause +val firstClause: Clause<S, C, K>
+

Inherited Properties

+ + + + + + + +
+requiredCommands +open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

+
+

Functions

+ + + + + + + + + + + + + + + +
+matchedClauses +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>

Determine which clauses are matched by the supplied commands

+
+toString +fun toString(): String
+verify +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>

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.

+
+

Companion Object Properties

+ + + + + + + +
+logger +val logger: <ERROR CLASS>
+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/logger.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/logger.html new file mode 100644 index 0000000000..b17e2ec5ff --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/logger.html @@ -0,0 +1,15 @@ + + +FirstComposition.logger - + + + +com.r3corda.core.contracts.clauses / FirstComposition / logger
+
+

logger

+ +val logger: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/matched-clauses.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/matched-clauses.html new file mode 100644 index 0000000000..eb6c10bdce --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/matched-clauses.html @@ -0,0 +1,16 @@ + + +FirstComposition.matchedClauses - + + + +com.r3corda.core.contracts.clauses / FirstComposition / matchedClauses
+
+

matchedClauses

+ +fun matchedClauses(commands: List<AuthenticatedObject<C>>): List<Clause<S, C, K>>
+

Determine which clauses are matched by the supplied commands

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/to-string.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/to-string.html new file mode 100644 index 0000000000..8cf0626196 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/to-string.html @@ -0,0 +1,15 @@ + + +FirstComposition.toString - + + + +com.r3corda.core.contracts.clauses / FirstComposition / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/verify.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/verify.html new file mode 100644 index 0000000000..0bd8e201a0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-first-composition/verify.html @@ -0,0 +1,43 @@ + + +FirstComposition.verify - + + + +com.r3corda.core.contracts.clauses / FirstComposition / verify
+
+

verify

+ +fun verify(tx: TransactionForContract, inputs: List<S>, outputs: List<S>, commands: List<AuthenticatedObject<C>>, groupingKey: K?): Set<C>
+

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.
+

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).

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/-init-.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/-init-.html index 668aa4d6cb..8e45c34aa6 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts.clauses / GroupClauseVerifier / <init>

<init>

-GroupClauseVerifier()
+GroupClauseVerifier(clause: Clause<S, C, K>)


diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/clause.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/clause.html new file mode 100644 index 0000000000..f729117609 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/clause.html @@ -0,0 +1,15 @@ + + +GroupClauseVerifier.clause - + + + +com.r3corda.core.contracts.clauses / GroupClauseVerifier / clause
+
+

clause

+ +val clause: Clause<S, C, K>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/get-execution-path.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/get-execution-path.html new file mode 100644 index 0000000000..d9c7027f25 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/get-execution-path.html @@ -0,0 +1,16 @@ + + +GroupClauseVerifier.getExecutionPath - + + + +com.r3corda.core.contracts.clauses / GroupClauseVerifier / getExecutionPath
+
+

getExecutionPath

+ +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>
+

Determine the subclauses which will be verified as a result of verifying this clause.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/group-states.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/group-states.html index e642a0d6c6..b3a71d5283 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/group-states.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/group-states.html @@ -8,7 +8,7 @@

groupStates

-abstract fun groupStates(tx: TransactionForContract): List<InOutGroup<S, T>>
+abstract fun groupStates(tx: TransactionForContract): List<InOutGroup<S, K>>


diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/index.html index bb5ac1edf8..427eb9adca 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/index.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts.clauses / GroupClauseVerifier

GroupClauseVerifier

-abstract class GroupClauseVerifier<S : ContractState, T : Any> : SingleClause
+abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any> : ConcreteClause<ContractState, C, Unit>


Constructors

@@ -17,7 +17,7 @@ <init> -GroupClauseVerifier() +GroupClauseVerifier(clause: Clause<S, C, K>) @@ -26,16 +26,9 @@ -clauses +clause -abstract val clauses: List<GroupClause<S, T>> - - - -requiredCommands - -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

- +val clause: Clause<S, C, K> @@ -44,16 +37,9 @@ -ifMatched +requiredCommands -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -63,21 +49,40 @@ +getExecutionPath + +open fun getExecutionPath(commands: List<AuthenticatedObject<C>>): List<Clause<*, *, *>>

Determine the subclauses which will be verified as a result of verifying this clause.

+ + + + groupStates -abstract fun groupStates(tx: TransactionForContract): List<InOutGroup<S, T>> +abstract fun groupStates(tx: TransactionForContract): List<InOutGroup<S, K>> verify -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause +open fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>

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.

+

Extension Functions

+ + + + + + + +
+matches +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+

Inheritors

@@ -85,13 +90,13 @@ if any matched.

+class Group : GroupClauseVerifier<State, Commands, Issued<Currency>> @@ -99,20 +104,20 @@ each group.

+class Group : GroupClauseVerifier<State, Commands, Issued<Terms>> +Group +class Group : GroupClauseVerifier<State, Commands, UniqueIdentifier>
Group -class Group : GroupClauseVerifier<State, Issued<Currency>>
Group -class Group : GroupClauseVerifier<State, Issued<Commodity>>

Grouping clause to extract input and output states into matched groups and then run a set of clauses over +class Group : GroupClauseVerifier<State, Commands, Issued<Commodity>>

Grouping clause to extract input and output states into matched groups and then run a set of clauses over each group.

Group -class Group<P> : GroupClauseVerifier<State<P>, Issued<Terms<P>>>

Parent clause for clauses that operate on grouped states (those which are fungible).

+class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>

Parent clause for clauses that operate on grouped states (those which are fungible).

Group -class Group : GroupClauseVerifier<State, Issued<Terms>>
-Group -class Group : GroupClauseVerifier<State, UniqueIdentifier>
diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/verify.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/verify.html index debb39a25e..ab0b81c22a 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/-group-clause-verifier/verify.html @@ -7,12 +7,31 @@ com.r3corda.core.contracts.clauses / GroupClauseVerifier / verify

verify

- -open fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>
-Overrides SingleVerify.verify
+ +open fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<C>>, groupingKey: Unit?): Set<C>

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

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 diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/index.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/index.html index a503910248..18b6eb7057 100644 --- a/docs/build/html/api/com.r3corda.core.contracts.clauses/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/index.html @@ -12,56 +12,51 @@ -Clause +AllComposition -interface Clause

A clause that can be matched as part of execution of a contract.

+class AllComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that all of the clauses must run for verification to pass.

-GroupClause +AnyComposition -interface GroupClause<in S : ContractState, in T : Any> : Clause, GroupVerify<S, T> +class AnyComposition<in S : ContractState, C : CommandData, in K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that any number of the clauses can run.

+ + + + +Clause + +interface Clause<in S : ContractState, C : CommandData, in K : Any> + + + +CompositeClause + +abstract class CompositeClause<in S : ContractState, C : CommandData, in K : Any> : Clause<S, C, K>

Abstract supertype for clauses which compose other clauses together in some logical manner.

+ + + + +ConcreteClause + +abstract class ConcreteClause<in S : ContractState, C : CommandData, in T : Any> : Clause<S, C, T>

Abstract supertype for clauses which provide their own verification logic, rather than delegating to subclauses. +By default these clauses are always matched (they have no required commands).

+ + + + +FirstComposition + +class FirstComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>

Compose a number of clauses, such that the first match is run, and it errors if none is run.

+ GroupClauseVerifier -abstract class GroupClauseVerifier<S : ContractState, T : Any> : SingleClause - - - -GroupVerify - -interface GroupVerify<in S, in T : Any> - - - -InterceptorClause - -class InterceptorClause : SingleClause

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.

- - - - -MatchBehaviour - -enum class MatchBehaviour - - - -SingleClause - -abstract class SingleClause : Clause, SingleVerify

A single verifiable clause. By default always matches, continues to the next clause when matched and errors -if not matched.

- - - - -SingleVerify - -interface SingleVerify +abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any> : ConcreteClause<ContractState, C, Unit> @@ -70,9 +65,16 @@ if not matched.

-verifyClauses +matches -fun verifyClauses(tx: TransactionForContract, clauses: List<SingleClause>, commands: Collection<AuthenticatedObject<CommandData>>): Unit

Verify a transaction against the given list of clauses.

+fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean

Determine if the given list of commands matches the required commands for a clause to trigger.

+ + + + +verifyClause + +fun <C : CommandData> verifyClause(tx: TransactionForContract, clause: Clause<ContractState, C, Unit>, commands: List<AuthenticatedObject<C>>): Unit

Verify a transaction against the given list of clauses.

diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/matches.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/matches.html new file mode 100644 index 0000000000..fcfe55a8f7 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/matches.html @@ -0,0 +1,16 @@ + + +matches - + + + +com.r3corda.core.contracts.clauses / matches
+
+

matches

+ +fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean
+

Determine if the given list of commands matches the required commands for a clause to trigger.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts.clauses/verify-clause.html b/docs/build/html/api/com.r3corda.core.contracts.clauses/verify-clause.html new file mode 100644 index 0000000000..abd2cb9dd2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts.clauses/verify-clause.html @@ -0,0 +1,26 @@ + + +verifyClause - + + + +com.r3corda.core.contracts.clauses / verifyClause
+
+

verifyClause

+ +fun <C : CommandData> verifyClause(tx: TransactionForContract, clause: Clause<ContractState, C, Unit>, commands: List<AuthenticatedObject<C>>): Unit
+

Verify a transaction against the given list of clauses.

+

Parameters

+ +tx - transaction to be verified.
+
+ +clauses - the clauses to verify.
+
+ +commands - commands extracted from the transaction, which are relevant to the +clauses.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/-init-.html new file mode 100644 index 0000000000..6ab244241e --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/-init-.html @@ -0,0 +1,24 @@ + + +ClientToServiceCommand.ExitCash.<init> - + + + +com.r3corda.core.contracts / ClientToServiceCommand / ExitCash / <init>
+
+

<init>

+ExitCash(amount: Amount<Currency>, issueRef: OpaqueBytes, id: UUID = UUID.randomUUID())
+

Exit cash from the ledger.

+

Parameters

+ +amount - the amount of currency to exit from the ledger.
+
+ +issueRef - the reference previously specified on the issuance.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/amount.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/amount.html new file mode 100644 index 0000000000..d84c638ff4 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/amount.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.ExitCash.amount - + + + +com.r3corda.core.contracts / ClientToServiceCommand / ExitCash / amount
+
+

amount

+ +val amount: Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/index.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/index.html new file mode 100644 index 0000000000..6b9b47f1c3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/index.html @@ -0,0 +1,64 @@ + + +ClientToServiceCommand.ExitCash - + + + +com.r3corda.core.contracts / ClientToServiceCommand / ExitCash
+
+

ExitCash

+class ExitCash : ClientToServiceCommand
+

Exit cash from the ledger.

+

Parameters

+ +amount - the amount of currency to exit from the ledger.
+
+ +issueRef - the reference previously specified on the issuance.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+

Constructors

+ + + + + + + +
+<init> +ExitCash(amount: Amount<Currency>, issueRef: OpaqueBytes, id: UUID = UUID.randomUUID())

Exit cash from the ledger.

+
+

Properties

+ + + + + + + + + + + +
+amount +val amount: Amount<Currency>
+issueRef +val issueRef: OpaqueBytes
+

Inherited Properties

+ + + + + + + +
+id +val id: UUID
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/issue-ref.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/issue-ref.html new file mode 100644 index 0000000000..fd66c5fe48 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-exit-cash/issue-ref.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.ExitCash.issueRef - + + + +com.r3corda.core.contracts / ClientToServiceCommand / ExitCash / issueRef
+
+

issueRef

+ +val issueRef: OpaqueBytes
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/-init-.html new file mode 100644 index 0000000000..2023e7bf62 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/-init-.html @@ -0,0 +1,31 @@ + + +ClientToServiceCommand.IssueCash.<init> - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash / <init>
+
+

<init>

+IssueCash(amount: Amount<Currency>, issueRef: OpaqueBytes, recipient: Party, notary: Party, id: UUID = UUID.randomUUID())
+

Issue cash state objects.

+

Parameters

+ +amount - the amount of currency to issue on to the ledger.
+
+ +issueRef - the reference to specify on the issuance, used to differentiate pools of cash. Convention is +to use the single byte "0x01" as a default.
+
+ +recipient - the party to issue the cash to.
+
+ +notary - the notary to use for this transaction.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/amount.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/amount.html new file mode 100644 index 0000000000..b5fe526a93 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/amount.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.IssueCash.amount - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash / amount
+
+

amount

+ +val amount: Amount<Currency>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/index.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/index.html new file mode 100644 index 0000000000..d2eb906e69 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/index.html @@ -0,0 +1,83 @@ + + +ClientToServiceCommand.IssueCash - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash
+
+

IssueCash

+class IssueCash : ClientToServiceCommand
+

Issue cash state objects.

+

Parameters

+ +amount - the amount of currency to issue on to the ledger.
+
+ +issueRef - the reference to specify on the issuance, used to differentiate pools of cash. Convention is +to use the single byte "0x01" as a default.
+
+ +recipient - the party to issue the cash to.
+
+ +notary - the notary to use for this transaction.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+

Constructors

+ + + + + + + +
+<init> +IssueCash(amount: Amount<Currency>, issueRef: OpaqueBytes, recipient: Party, notary: Party, id: UUID = UUID.randomUUID())

Issue cash state objects.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + +
+amount +val amount: Amount<Currency>
+issueRef +val issueRef: OpaqueBytes
+notary +val notary: Party
+recipient +val recipient: Party
+

Inherited Properties

+ + + + + + + +
+id +val id: UUID
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/issue-ref.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/issue-ref.html new file mode 100644 index 0000000000..fef8beab90 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/issue-ref.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.IssueCash.issueRef - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash / issueRef
+
+

issueRef

+ +val issueRef: OpaqueBytes
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/notary.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/notary.html new file mode 100644 index 0000000000..d634bbdd53 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/notary.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.IssueCash.notary - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash / notary
+
+

notary

+ +val notary: Party
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/recipient.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/recipient.html new file mode 100644 index 0000000000..a6157b093c --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-issue-cash/recipient.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.IssueCash.recipient - + + + +com.r3corda.core.contracts / ClientToServiceCommand / IssueCash / recipient
+
+

recipient

+ +val recipient: Party
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/-init-.html new file mode 100644 index 0000000000..ab19831b09 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/-init-.html @@ -0,0 +1,24 @@ + + +ClientToServiceCommand.PayCash.<init> - + + + +com.r3corda.core.contracts / ClientToServiceCommand / PayCash / <init>
+
+

<init>

+PayCash(amount: Amount<Issued<Currency>>, recipient: Party, id: UUID = UUID.randomUUID())
+

Pay cash to someone else.

+

Parameters

+ +amount - the amount of currency to issue on to the ledger.
+
+ +recipient - the party to issue the cash to.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/amount.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/amount.html new file mode 100644 index 0000000000..3cd7aca58b --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/amount.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.PayCash.amount - + + + +com.r3corda.core.contracts / ClientToServiceCommand / PayCash / amount
+
+

amount

+ +val amount: Amount<Issued<Currency>>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/index.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/index.html new file mode 100644 index 0000000000..0ef6b5e82f --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/index.html @@ -0,0 +1,64 @@ + + +ClientToServiceCommand.PayCash - + + + +com.r3corda.core.contracts / ClientToServiceCommand / PayCash
+
+

PayCash

+class PayCash : ClientToServiceCommand
+

Pay cash to someone else.

+

Parameters

+ +amount - the amount of currency to issue on to the ledger.
+
+ +recipient - the party to issue the cash to.
+
+ +id - the ID to be provided in events resulting from this request.
+
+
+

Constructors

+ + + + + + + +
+<init> +PayCash(amount: Amount<Issued<Currency>>, recipient: Party, id: UUID = UUID.randomUUID())

Pay cash to someone else.

+
+

Properties

+ + + + + + + + + + + +
+amount +val amount: Amount<Issued<Currency>>
+recipient +val recipient: Party
+

Inherited Properties

+ + + + + + + +
+id +val id: UUID
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/recipient.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/recipient.html new file mode 100644 index 0000000000..6942a1b460 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/-pay-cash/recipient.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.PayCash.recipient - + + + +com.r3corda.core.contracts / ClientToServiceCommand / PayCash / recipient
+
+

recipient

+ +val recipient: Party
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/id.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/id.html new file mode 100644 index 0000000000..a3c14fe49d --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/id.html @@ -0,0 +1,15 @@ + + +ClientToServiceCommand.id - + + + +com.r3corda.core.contracts / ClientToServiceCommand / id
+
+

id

+ +val id: UUID
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/index.html b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/index.html new file mode 100644 index 0000000000..984186a0a3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.contracts/-client-to-service-command/index.html @@ -0,0 +1,81 @@ + + +ClientToServiceCommand - + + + +com.r3corda.core.contracts / ClientToServiceCommand
+
+

ClientToServiceCommand

+sealed class ClientToServiceCommand
+

A command from the monitoring client, to the node.

+

Parameters

+ +id - ID used to tag event(s) resulting from a command.
+
+
+

Types

+ + + + + + + + + + + + + + + +
+ExitCash +class ExitCash : ClientToServiceCommand

Exit cash from the ledger.

+
+IssueCash +class IssueCash : ClientToServiceCommand

Issue cash state objects.

+
+PayCash +class PayCash : ClientToServiceCommand

Pay cash to someone else.

+
+

Properties

+ + + + + + + +
+id +val id: UUID
+

Inheritors

+ + + + + + + + + + + + + + + +
+ExitCash +class ExitCash : ClientToServiceCommand

Exit cash from the ledger.

+
+IssueCash +class IssueCash : ClientToServiceCommand

Issue cash state objects.

+
+PayCash +class PayCash : ClientToServiceCommand

Pay cash to someone else.

+
+ + diff --git a/docs/build/html/api/com.r3corda.core.contracts/-commodity/-init-.html b/docs/build/html/api/com.r3corda.core.contracts/-commodity/-init-.html index 20def35787..368ef836b2 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-commodity/-init-.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-commodity/-init-.html @@ -7,7 +7,20 @@ com.r3corda.core.contracts / Commodity / <init>

<init>

-Commodity(symbol: String, displayName: String, commodityCode: String = symbol, defaultFractionDigits: Int = 0)
+Commodity(commodityCode: String, displayName: String, defaultFractionDigits: Int = 0)
+

Class representing a commodity, as an equivalent to the Currency class. This exists purely to enable the +CommodityContract contract, and is likely to change in future.

+

Parameters

+ +commodityCode - a unique code for the commodity. No specific registry for these is currently defined, although +this is likely to change in future.
+
+ +displayName - human readable name for the commodity.
+
+ +defaultFractionDigits - the number of digits normally after the decimal point when referring to quantities of +this commodity.


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-commodity/get-instance.html b/docs/build/html/api/com.r3corda.core.contracts/-commodity/get-instance.html index 479fbba16e..02027e44e7 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-commodity/get-instance.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-commodity/get-instance.html @@ -8,7 +8,7 @@

getInstance

-fun getInstance(symbol: String): Commodity?
+fun getInstance(commodityCode: String): Commodity?


diff --git a/docs/build/html/api/com.r3corda.core.contracts/-commodity/index.html b/docs/build/html/api/com.r3corda.core.contracts/-commodity/index.html index abcea31f87..55ba06973a 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-commodity/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-commodity/index.html @@ -8,6 +8,19 @@

Commodity

data class Commodity
+

Class representing a commodity, as an equivalent to the Currency class. This exists purely to enable the +CommodityContract contract, and is likely to change in future.

+

Parameters

+ +commodityCode - a unique code for the commodity. No specific registry for these is currently defined, although +this is likely to change in future.
+
+ +displayName - human readable name for the commodity.
+
+ +defaultFractionDigits - the number of digits normally after the decimal point when referring to quantities of +this commodity.


Constructors

@@ -17,7 +30,9 @@ <init> -Commodity(symbol: String, displayName: String, commodityCode: String = symbol, defaultFractionDigits: Int = 0) +Commodity(commodityCode: String, displayName: String, defaultFractionDigits: Int = 0)

Class representing a commodity, as an equivalent to the Currency class. This exists purely to enable the +CommodityContract contract, and is likely to change in future.

+ @@ -42,12 +57,6 @@ val displayName: String - - -symbol - -val symbol: String -

Companion Object Functions

@@ -57,7 +66,7 @@ getInstance -fun getInstance(symbol: String): Commodity? +fun getInstance(commodityCode: String): Commodity? 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 69f1402e7d..10b18a7f4f 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 @@ -100,7 +100,7 @@ to be netted/merged, with settlement only for any remainder amount.

OnLedgerAsset -abstract class OnLedgerAsset<T : Any, S : FungibleAsset<T>> : Contract

An asset transaction may split and merge assets represented by a set of (issuer, depositRef) pairs, across multiple +abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : Contract

An asset transaction may split and merge assets 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.core.contracts/-linear-state/-clause-verifier/index.html b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/index.html index 457b1eeac4..5b541d3e4b 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/index.html @@ -7,7 +7,7 @@ com.r3corda.core.contracts / LinearState / ClauseVerifier

ClauseVerifier

-class ClauseVerifier<S : LinearState> : SingleClause
+class ClauseVerifier<S : LinearState> : ConcreteClause<ContractState, CommandData, Unit>

Standard clause to verify the LinearState safety properties.



@@ -39,23 +39,9 @@ -ifMatched +requiredCommands -open val ifMatched: MatchBehaviour

Behaviour if this clause is not matches

- - - - -ifNotMatched - -open val ifNotMatched: MatchBehaviour

Behaviour if this clause is matched

- - - - -requiredCommands - -open val requiredCommands: Set<Class<out CommandData>>

Classes for commands which must ALL be present in transaction for this clause to be triggered

+open val requiredCommands: Set<Class<out CommandData>>

Determine whether this clause runs or not

@@ -67,7 +53,7 @@ verify -fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>

Verify the transaction matches the conditions from this clause. For example, a "no zero amount output" clause +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<CommandData>>, groupingKey: Unit?): Set<CommandData>

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.

diff --git a/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/verify.html b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/verify.html index b701069222..3cd40ca17f 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/verify.html +++ b/docs/build/html/api/com.r3corda.core.contracts/-linear-state/-clause-verifier/verify.html @@ -7,12 +7,31 @@ com.r3corda.core.contracts / LinearState / ClauseVerifier / verify

verify

- -fun verify(tx: TransactionForContract, commands: Collection<AuthenticatedObject<CommandData>>): Set<CommandData>
-Overrides SingleVerify.verify
+ +fun verify(tx: TransactionForContract, inputs: List<ContractState>, outputs: List<ContractState>, commands: List<AuthenticatedObject<CommandData>>, groupingKey: Unit?): Set<CommandData>

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.

+

Parameters

+ +tx - the full transaction being verified. This is provided for cases where clauses need to access +states or commands outside of their normal scope.
+
+ +inputs - input states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +outputs - output states which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +commands - commands which are relevant to this clause. By default this is the set passed into verifyClause, +but may be further reduced by clauses such as GroupClauseVerifier.
+
+ +groupingKey - a grouping key applied to states and commands, where applicable. Taken from +TransactionForContract.InOutGroup.

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 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 b99a9cc180..8fb1607185 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 @@ -21,7 +21,7 @@ ClauseVerifier -class ClauseVerifier<S : LinearState> : SingleClause

Standard clause to verify the LinearState safety properties.

+class ClauseVerifier<S : LinearState> : ConcreteClause<ContractState, CommandData, Unit>

Standard clause to verify the LinearState safety properties.

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 5075204587..cedeee48f2 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 @@ -57,6 +57,12 @@ +Issue + +class Issue : TypeOnlyCommandData, Commands + + + Mature class Mature : TypeOnlyCommandData, Commands @@ -69,12 +75,6 @@ -Move - -class Move : TypeOnlyCommandData, Commands - - - Move class Move : TypeOnlyCommandData, Commands @@ -85,6 +85,18 @@ class Pay : TypeOnlyCommandData, Commands + + +Redeem + +class Redeem : TypeOnlyCommandData, Commands + + + +Redeem + +class Redeem : TypeOnlyCommandData, Commands + 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 f8f6847d7e..724580bc7d 100644 --- a/docs/build/html/api/com.r3corda.core.contracts/index.html +++ b/docs/build/html/api/com.r3corda.core.contracts/index.html @@ -61,6 +61,13 @@ no staff are around to handle problems.

+ClientToServiceCommand + +sealed class ClientToServiceCommand

A command from the monitoring client, to the node.

+ + + + Command data class Command

Command data/content plus pubkey pair: the signature is stored at the end of the serialized bytes

@@ -77,7 +84,9 @@ no staff are around to handle problems.

Commodity -data class Commodity +data class Commodity

Class representing a commodity, as an equivalent to the Currency class. This exists purely to enable the +CommodityContract contract, and is likely to change in future.

+ diff --git a/docs/build/html/api/com.r3corda.core.messaging/-single-message-recipient.html b/docs/build/html/api/com.r3corda.core.messaging/-single-message-recipient.html index ed234eead5..8ca345d08d 100644 --- a/docs/build/html/api/com.r3corda.core.messaging/-single-message-recipient.html +++ b/docs/build/html/api/com.r3corda.core.messaging/-single-message-recipient.html @@ -16,12 +16,6 @@ -Address - -data class Address : SingleMessageRecipient - - - Handle class Handle : SingleMessageRecipient @@ -32,6 +26,18 @@ data class MockAddress : SingleMessageRecipient + + +NetworkMapAddress + +data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress + + + +NodeAddress + +data class NodeAddress : SingleMessageRecipient, ArtemisAddress + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/-modified.html b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/-modified.html new file mode 100644 index 0000000000..1d96ff5eb1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/-modified.html @@ -0,0 +1,14 @@ + + +NetworkMapCache.MapChangeType.Modified - + + + +com.r3corda.core.node.services / NetworkMapCache / MapChangeType / Modified
+
+

Modified

+Modified
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/index.html b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/index.html index 5c7c99b8fa..b0a2c52669 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change-type/index.html @@ -25,6 +25,12 @@ + + +Modified + + + diff --git a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/-init-.html b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/-init-.html index 5a668de761..5e0ad020aa 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/-init-.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/-init-.html @@ -7,7 +7,7 @@ com.r3corda.core.node.services / NetworkMapCache / MapChange / <init>

<init>

-MapChange(node: NodeInfo, type: MapChangeType)
+MapChange(node: NodeInfo, prevNodeInfo: NodeInfo?, type: MapChangeType)


diff --git a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/index.html b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/index.html index f7124c3142..f26fd015c7 100644 --- a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/index.html +++ b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/index.html @@ -17,7 +17,7 @@ <init> -MapChange(node: NodeInfo, type: MapChangeType) +MapChange(node: NodeInfo, prevNodeInfo: NodeInfo?, type: MapChangeType) @@ -32,6 +32,12 @@ +prevNodeInfo + +val prevNodeInfo: NodeInfo? + + + type val type: MapChangeType diff --git a/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/prev-node-info.html b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/prev-node-info.html new file mode 100644 index 0000000000..42c5dda103 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.node.services/-network-map-cache/-map-change/prev-node-info.html @@ -0,0 +1,15 @@ + + +NetworkMapCache.MapChange.prevNodeInfo - + + + +com.r3corda.core.node.services / NetworkMapCache / MapChange / prevNodeInfo
+
+

prevNodeInfo

+ +val prevNodeInfo: NodeInfo?
+
+
+ + 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 6752138756..2bee4712e2 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 @@ -148,6 +148,14 @@ we do not support coercing numeric types in the reflective search for matching c +BroadcastTransactionProtocol + +class BroadcastTransactionProtocol : ProtocolLogic<Unit>

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+ + + + Buyer class Buyer : ProtocolLogic<SignedTransaction> @@ -169,6 +177,13 @@ timestamp is correct and none of its inputs have been used in another completed +FinalityProtocol + +class FinalityProtocol : ProtocolLogic<Unit>

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+ + + + 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.

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 cb51806cfa..a0850c6444 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 @@ -22,6 +22,20 @@ +machineId + +abstract val machineId: Long

Unique ID for this machine, valid only while it is in memory.

+ + + + +resultFuture + +abstract val resultFuture: <ERROR CLASS><R>

This future will complete when the call method returns.

+ + + + serviceHub abstract val serviceHub: ServiceHub diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/machine-id.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/machine-id.html new file mode 100644 index 0000000000..ebedcf3b62 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/machine-id.html @@ -0,0 +1,16 @@ + + +ProtocolStateMachine.machineId - + + + +com.r3corda.core.protocols / ProtocolStateMachine / machineId
+
+

machineId

+ +abstract val machineId: Long
+

Unique ID for this machine, valid only while it is in memory.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/result-future.html b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/result-future.html new file mode 100644 index 0000000000..51a14cb2ea --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.protocols/-protocol-state-machine/result-future.html @@ -0,0 +1,16 @@ + + +ProtocolStateMachine.resultFuture - + + + +com.r3corda.core.protocols / ProtocolStateMachine / resultFuture
+
+

resultFuture

+ +abstract val resultFuture: <ERROR CLASS><R>
+

This future will complete when the call method returns.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/-state/participants.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/-state/participants.html index c0d5aab365..84e6269fb0 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/-state/participants.html +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/-state/participants.html @@ -12,7 +12,7 @@ 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 +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 diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/clause.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/clause.html new file mode 100644 index 0000000000..e42d3912d1 --- /dev/null +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/clause.html @@ -0,0 +1,15 @@ + + +DummyLinearContract.clause - + + + +com.r3corda.core.testing / DummyLinearContract / clause
+
+

clause

+ +val clause: Clause<ContractState, CommandData, Unit>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/index.html b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/index.html index d9b9503bae..dbdd472a85 100644 --- a/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/index.html +++ b/docs/build/html/api/com.r3corda.core.testing/-dummy-linear-contract/index.html @@ -37,6 +37,12 @@ +clause + +val clause: Clause<ContractState, CommandData, Unit> + + + legalContractReference val legalContractReference: SecureHash

Unparsed reference to the natural language contract that this code is supposed to express (usually a hash of 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 4651edb188..fa8e404ff4 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 @@ -80,6 +80,12 @@ +BROADCASTING + +object BROADCASTING : Step + + + COPYING_TO_REGULATOR object COPYING_TO_REGULATOR : Step @@ -110,6 +116,12 @@ +NOTARISING + +object NOTARISING : Step + + + NOTARY object NOTARY : Step 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 f9729f1cea..9060b40041 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 @@ -120,8 +120,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> 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 a9d08f393e..2c38c30326 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 @@ -101,8 +101,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/index.html b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/index.html index c273eecb4c..4bac2c777c 100644 --- a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/index.html +++ b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/index.html @@ -29,7 +29,7 @@ startClient -abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

+abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

diff --git a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/start-client.html b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/start-client.html index e6b3cde9b2..3af2e650af 100644 --- a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/start-client.html +++ b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-exposed-interface/start-client.html @@ -7,8 +7,8 @@ com.r3corda.node.driver / DriverDSLExposedInterface / startClient

startClient

- -abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+ +abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

Parameters

@@ -17,9 +17,6 @@ serverAddress - the artemis server to connect to, for example a Node.

- -clientAddress - the address of the client (this is not bound by the client), defaults to serverAddress if null.
-

diff --git a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-internal-interface/index.html b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-internal-interface/index.html index 63c37ed23e..af76d448c6 100644 --- a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-internal-interface/index.html +++ b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l-internal-interface/index.html @@ -45,7 +45,7 @@ startClient -abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

+abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

diff --git a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/index.html b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/index.html index 005a888dd1..7118eaee5e 100644 --- a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/index.html +++ b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/index.html @@ -92,7 +92,7 @@ startClient -fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

+fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>

Starts an ArtemisMessagingClient.

diff --git a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/start-client.html b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/start-client.html index 2854009211..363b58bbad 100644 --- a/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/start-client.html +++ b/docs/build/html/api/com.r3corda.node.driver/-driver-d-s-l/start-client.html @@ -7,8 +7,8 @@ com.r3corda.node.driver / DriverDSL / startClient

startClient

- -fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+ +fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>
Overrides DriverDSLExposedInterface.startClient

Starts an ArtemisMessagingClient.

Parameters

@@ -18,9 +18,6 @@ Overrides DriverD serverAddress - the artemis server to connect to, for example a Node.

- -clientAddress - the address of the client (this is not bound by the client), defaults to serverAddress if null.
-

diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/-init-.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/-init-.html index b103aac4d6..0c7a44c4ae 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.messaging / ArtemisMessagingClient / <init>

<init>

-ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myHostPort: <ERROR CLASS>, executor: AffinityExecutor)
+ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myIdentity: PublicKey?, executor: AffinityExecutor, persistentInbox: Boolean = true)

This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product. Artemis is a message queue broker and here we run a client connecting to the specified broker instance ArtemisMessagingServer.

@@ -20,8 +20,16 @@ through into Artemis and from there, back through to senders.

serverHostPort - The address of the broker instance to connect to (might be running in the same process)

- -myHostPort - What host and port to use as an address for incoming messages
+ +myIdentity - Either the public key to be used as the ArtemisMQ address and queue name for the node globally, or null to indicate +that this is a NetworkMapService node which will be bound globally to the name "networkmap"
+
+ +executor - An executor to run received message tasks upon.
+
+ +persistentInbox - If true the inbox will be created persistent if not already created. +If false the inbox queue will be transient, which is appropriate for UI clients for example.


diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/index.html index dd155ace91..bc70fa0463 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/index.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/index.html @@ -20,8 +20,16 @@ through into Artemis and from there, back through to senders.

serverHostPort - The address of the broker instance to connect to (might be running in the same process)

- -myHostPort - What host and port to use as an address for incoming messages
+ +myIdentity - Either the public key to be used as the ArtemisMQ address and queue name for the node globally, or null to indicate +that this is a NetworkMapService node which will be bound globally to the name "networkmap"
+
+ +executor - An executor to run received message tasks upon.
+
+ +persistentInbox - If true the inbox will be created persistent if not already created. +If false the inbox queue will be transient, which is appropriate for UI clients for example.


Types

@@ -43,7 +51,7 @@ through into Artemis and from there, back through to senders.

<init> -ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myHostPort: <ERROR CLASS>, executor: AffinityExecutor)

This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product. +ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myIdentity: PublicKey?, executor: AffinityExecutor, persistentInbox: Boolean = true)

This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product. Artemis is a message queue broker and here we run a client connecting to the specified broker instance ArtemisMessagingServer.

@@ -63,14 +71,20 @@ Artemis is a message queue broker and here we run a client connecting to the spe myAddress -val myAddress: SingleMessageRecipient

Returns an address that refers to this node.

+val myAddress: SingleMessageRecipient

Apart from the NetworkMapService this is the only other address accessible to the node outside of lookups against the NetworkMapCache.

-myHostPort +myIdentity -val myHostPort: <ERROR CLASS> +val myIdentity: PublicKey? + + + +persistentInbox + +val persistentInbox: Boolean @@ -178,6 +192,12 @@ the CA certs in Node resources. Then provision KeyStores into certificates folde fun tcpTransport(direction: ConnectionDirection, host: String, port: Int): <ERROR CLASS> + + +tryParseKeyFromQueueName + +fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey? +

Companion Object Properties

@@ -208,16 +228,12 @@ the CA certs in Node resources. Then provision KeyStores into certificates folde -makeRecipient +makeNetworkMapAddress -fun makeRecipient(hostAndPort: <ERROR CLASS>): SingleMessageRecipient

Temp helper until network map is established.

-fun makeRecipient(hostname: String): <ERROR CLASS> - - - -toHostAndPort - -fun toHostAndPort(hostname: String): <ERROR CLASS> +fun makeNetworkMapAddress(hostAndPort: <ERROR CLASS>): SingleMessageRecipient

This should be the only way to generate an ArtemisAddress and that only of the remote NetworkMapService node. +All other addresses come from the NetworkMapCache, or myAddress below. +The node will populate with their own identity based address when they register with the NetworkMapService.

+ diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/make-network-map-address.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/make-network-map-address.html new file mode 100644 index 0000000000..b7dce37557 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/make-network-map-address.html @@ -0,0 +1,18 @@ + + +ArtemisMessagingClient.makeNetworkMapAddress - + + + +com.r3corda.node.services.messaging / ArtemisMessagingClient / makeNetworkMapAddress
+
+

makeNetworkMapAddress

+ +fun makeNetworkMapAddress(hostAndPort: <ERROR CLASS>): SingleMessageRecipient
+

This should be the only way to generate an ArtemisAddress and that only of the remote NetworkMapService node. +All other addresses come from the NetworkMapCache, or myAddress below. +The node will populate with their own identity based address when they register with the NetworkMapService.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-address.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-address.html index 54f86ac166..1a08f712b4 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-address.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-address.html @@ -10,7 +10,7 @@ val myAddress: SingleMessageRecipient
Overrides MessagingService.myAddress
-

Returns an address that refers to this node.

+

Apart from the NetworkMapService this is the only other address accessible to the node outside of lookups against the NetworkMapCache.



diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-identity.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-identity.html new file mode 100644 index 0000000000..f1218b668f --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/my-identity.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingClient.myIdentity - + + + +com.r3corda.node.services.messaging / ArtemisMessagingClient / myIdentity
+
+

myIdentity

+ +val myIdentity: PublicKey?
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/persistent-inbox.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/persistent-inbox.html new file mode 100644 index 0000000000..0b1a22ff21 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-client/persistent-inbox.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingClient.persistentInbox - + + + +com.r3corda.node.services.messaging / ArtemisMessagingClient / persistentInbox
+
+

persistentInbox

+ +val persistentInbox: Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/host-and-port.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/host-and-port.html new file mode 100644 index 0000000000..7eaab899e6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/host-and-port.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.ArtemisAddress.hostAndPort - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / ArtemisAddress / hostAndPort
+
+

hostAndPort

+ +abstract val hostAndPort: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/index.html new file mode 100644 index 0000000000..65c76e5625 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/index.html @@ -0,0 +1,48 @@ + + +ArtemisMessagingComponent.ArtemisAddress - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / ArtemisAddress
+
+

ArtemisAddress

+protected interface ArtemisAddress
+
+
+

Properties

+ + + + + + + + + + + +
+hostAndPort +abstract val hostAndPort: <ERROR CLASS>
+queueName +abstract val queueName: <ERROR CLASS>
+

Inheritors

+ + + + + + + + + + + +
+NetworkMapAddress +data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress
+NodeAddress +data class NodeAddress : SingleMessageRecipient, ArtemisAddress
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/queue-name.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/queue-name.html new file mode 100644 index 0000000000..d5acd14154 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-artemis-address/queue-name.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.ArtemisAddress.queueName - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / ArtemisAddress / queueName
+
+

queueName

+ +abstract val queueName: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-n-e-t-w-o-r-k_-m-a-p_-a-d-d-r-e-s-s.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-n-e-t-w-o-r-k_-m-a-p_-a-d-d-r-e-s-s.html new file mode 100644 index 0000000000..f2fcf25ca2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-n-e-t-w-o-r-k_-m-a-p_-a-d-d-r-e-s-s.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.NETWORK_MAP_ADDRESS - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NETWORK_MAP_ADDRESS
+
+

NETWORK_MAP_ADDRESS

+ +protected val NETWORK_MAP_ADDRESS: <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/-init-.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/-init-.html new file mode 100644 index 0000000000..7db67c61ae --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/-init-.html @@ -0,0 +1,14 @@ + + +ArtemisMessagingComponent.NetworkMapAddress.<init> - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NetworkMapAddress / <init>
+
+

<init>

+NetworkMapAddress(hostAndPort: <ERROR CLASS>)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/host-and-port.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/host-and-port.html new file mode 100644 index 0000000000..f2f7cdc85a --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/host-and-port.html @@ -0,0 +1,16 @@ + + +ArtemisMessagingComponent.NetworkMapAddress.hostAndPort - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NetworkMapAddress / hostAndPort
+
+

hostAndPort

+ +val hostAndPort: <ERROR CLASS>
+Overrides ArtemisAddress.hostAndPort
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/index.html new file mode 100644 index 0000000000..4b38a4149c --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/index.html @@ -0,0 +1,42 @@ + + +ArtemisMessagingComponent.NetworkMapAddress - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NetworkMapAddress
+
+

NetworkMapAddress

+protected data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress
+
+
+

Constructors

+ + + + + + + +
+<init> +NetworkMapAddress(hostAndPort: <ERROR CLASS>)
+

Properties

+ + + + + + + + + + + +
+hostAndPort +val hostAndPort: <ERROR CLASS>
+queueName +val queueName: <ERROR CLASS>
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/queue-name.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/queue-name.html new file mode 100644 index 0000000000..ffbd3b40ab --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-network-map-address/queue-name.html @@ -0,0 +1,16 @@ + + +ArtemisMessagingComponent.NetworkMapAddress.queueName - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NetworkMapAddress / queueName
+
+

queueName

+ +val queueName: <ERROR CLASS>
+Overrides ArtemisAddress.queueName
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/-init-.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/-init-.html new file mode 100644 index 0000000000..e61e84b28d --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/-init-.html @@ -0,0 +1,14 @@ + + +ArtemisMessagingComponent.NodeAddress.<init> - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress / <init>
+
+

<init>

+NodeAddress(identity: PublicKey, hostAndPort: <ERROR CLASS>)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/host-and-port.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/host-and-port.html new file mode 100644 index 0000000000..98a99a1adb --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/host-and-port.html @@ -0,0 +1,16 @@ + + +ArtemisMessagingComponent.NodeAddress.hostAndPort - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress / hostAndPort
+
+

hostAndPort

+ +val hostAndPort: <ERROR CLASS>
+Overrides ArtemisAddress.hostAndPort
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/identity.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/identity.html new file mode 100644 index 0000000000..0b161192bc --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/identity.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.NodeAddress.identity - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress / identity
+
+

identity

+ +val identity: PublicKey
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/index.html new file mode 100644 index 0000000000..82f9cea91b --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/index.html @@ -0,0 +1,59 @@ + + +ArtemisMessagingComponent.NodeAddress - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress
+
+

NodeAddress

+protected data class NodeAddress : SingleMessageRecipient, ArtemisAddress
+
+
+

Constructors

+ + + + + + + +
+<init> +NodeAddress(identity: PublicKey, hostAndPort: <ERROR CLASS>)
+

Properties

+ + + + + + + + + + + + + + + +
+hostAndPort +val hostAndPort: <ERROR CLASS>
+identity +val identity: PublicKey
+queueName +val queueName: <ERROR CLASS>
+

Functions

+ + + + + + + +
+toString +fun toString(): String
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/queue-name.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/queue-name.html new file mode 100644 index 0000000000..b111deaece --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/queue-name.html @@ -0,0 +1,16 @@ + + +ArtemisMessagingComponent.NodeAddress.queueName - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress / queueName
+
+

queueName

+ +val queueName: <ERROR CLASS>
+Overrides ArtemisAddress.queueName
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/to-string.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/to-string.html new file mode 100644 index 0000000000..9fc339af8f --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-node-address/to-string.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.NodeAddress.toString - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / NodeAddress / toString
+
+

toString

+ +fun toString(): String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-p-e-e-r-s_-p-r-e-f-i-x.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-p-e-e-r-s_-p-r-e-f-i-x.html new file mode 100644 index 0000000000..dc32811e41 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/-p-e-e-r-s_-p-r-e-f-i-x.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.PEERS_PREFIX - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / PEERS_PREFIX
+
+

PEERS_PREFIX

+ +const val PEERS_PREFIX: String
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/index.html index ed5baced0c..083bd6b9f0 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/index.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/index.html @@ -22,9 +22,9 @@ -Address +ArtemisAddress -data class Address : SingleMessageRecipient +interface ArtemisAddress @@ -32,6 +32,18 @@ enum class ConnectionDirection + + +NetworkMapAddress + +data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress + + + +NodeAddress + +data class NodeAddress : SingleMessageRecipient, ArtemisAddress +

Constructors

@@ -80,6 +92,12 @@ the CA certs in Node resources. Then provision KeyStores into certificates folde fun tcpTransport(direction: ConnectionDirection, host: String, port: Int): <ERROR CLASS> + + +tryParseKeyFromQueueName + +fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey? +

Inherited Functions

@@ -93,6 +111,38 @@ the CA certs in Node resources. Then provision KeyStores into certificates folde +

Companion Object Properties

+ + + + + + + + + + + +
+NETWORK_MAP_ADDRESS +val NETWORK_MAP_ADDRESS: <ERROR CLASS>
+PEERS_PREFIX +const val PEERS_PREFIX: String
+

Companion Object Functions

+ + + + + + + +
+toQueueName +fun toQueueName(target: MessageRecipients): <ERROR CLASS>

Assuming the passed in target address is actually an ArtemisAddress will extract the queue name used. +For now the queue name is the Base58 version of the nodes identity. +This should only be used in the internals of the messaging services to keep addressing opaque for the future. +N.B. Marked as JvmStatic to allow use in the inherited classes.

+

Inheritors

diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/to-queue-name.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/to-queue-name.html new file mode 100644 index 0000000000..32f0d86d45 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/to-queue-name.html @@ -0,0 +1,19 @@ + + +ArtemisMessagingComponent.toQueueName - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / toQueueName
+
+

toQueueName

+ +protected fun toQueueName(target: MessageRecipients): <ERROR CLASS>
+

Assuming the passed in target address is actually an ArtemisAddress will extract the queue name used. +For now the queue name is the Base58 version of the nodes identity. +This should only be used in the internals of the messaging services to keep addressing opaque for the future. +N.B. Marked as JvmStatic to allow use in the inherited classes.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/try-parse-key-from-queue-name.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/try-parse-key-from-queue-name.html new file mode 100644 index 0000000000..b7830ae433 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-component/try-parse-key-from-queue-name.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingComponent.tryParseKeyFromQueueName - + + + +com.r3corda.node.services.messaging / ArtemisMessagingComponent / tryParseKeyFromQueueName
+
+

tryParseKeyFromQueueName

+ +protected fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey?
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/-init-.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/-init-.html index 00fe845ae3..f74011d8a9 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.messaging / ArtemisMessagingServer / <init>

<init>

-ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>)
+ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>, networkMapCache: NetworkMapCache)

This class configures and manages an Apache Artemis message queue broker.

Nodes communication is managed using an Artemis specific protocol, but it supports other protocols like AMQP/1.0 as well for interop.

diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/add-connector.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/add-connector.html new file mode 100644 index 0000000000..ecdcee3d01 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/add-connector.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.addConnector - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / addConnector
+
+

addConnector

+ +fun addConnector(hostAndPort: <ERROR CLASS>): <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-exists.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-exists.html new file mode 100644 index 0000000000..76b367d81c --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-exists.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.bridgeExists - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / bridgeExists
+
+

bridgeExists

+ +fun bridgeExists(name: <ERROR CLASS>): <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-to-network-map-service.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-to-network-map-service.html new file mode 100644 index 0000000000..8417ea9724 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/bridge-to-network-map-service.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.bridgeToNetworkMapService - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / bridgeToNetworkMapService
+
+

bridgeToNetworkMapService

+ +fun bridgeToNetworkMapService(networkMapService: NodeInfo?): Unit
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/connector-exists.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/connector-exists.html new file mode 100644 index 0000000000..8f9d47b976 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/connector-exists.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.connectorExists - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / connectorExists
+
+

connectorExists

+ +fun connectorExists(hostAndPort: <ERROR CLASS>): Boolean
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/deploy-bridge.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/deploy-bridge.html new file mode 100644 index 0000000000..ff260b3639 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/deploy-bridge.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.deployBridge - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / deployBridge
+
+

deployBridge

+ +fun deployBridge(hostAndPort: <ERROR CLASS>, name: <ERROR CLASS>): <ERROR CLASS>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/index.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/index.html index ce2e79b384..ca1b2fc878 100644 --- a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/index.html +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/index.html @@ -25,7 +25,7 @@ a fully connected network, trusted network or on localhost.

@@ -35,16 +35,16 @@ a fully connected network, trusted network or on localhost.

- - - - + + + +
<init> -ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>)

This class configures and manages an Apache Artemis message queue broker.

+ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>, networkMapCache: NetworkMapCache)

This class configures and manages an Apache Artemis message queue broker.

-myAddress -val myAddress: SingleMessageRecipient
myHostPort val myHostPort: <ERROR CLASS>
+networkMapCache +val networkMapCache: NetworkMapCache

Inherited Properties

@@ -69,6 +69,36 @@ a fully connected network, trusted network or on localhost.

+addConnector + +fun addConnector(hostAndPort: <ERROR CLASS>): <ERROR CLASS> + + + +bridgeExists + +fun bridgeExists(name: <ERROR CLASS>): <ERROR CLASS> + + + +bridgeToNetworkMapService + +fun bridgeToNetworkMapService(networkMapService: NodeInfo?): Unit + + + +connectorExists + +fun connectorExists(hostAndPort: <ERROR CLASS>): Boolean + + + +deployBridge + +fun deployBridge(hostAndPort: <ERROR CLASS>, name: <ERROR CLASS>): <ERROR CLASS> + + + start fun start(): Unit @@ -98,6 +128,12 @@ the CA certs in Node resources. Then provision KeyStores into certificates folde fun tcpTransport(direction: ConnectionDirection, host: String, port: Int): <ERROR CLASS> + + +tryParseKeyFromQueueName + +fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey? +

Companion Object Properties

diff --git a/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/network-map-cache.html b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/network-map-cache.html new file mode 100644 index 0000000000..18347e4b2c --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.messaging/-artemis-messaging-server/network-map-cache.html @@ -0,0 +1,15 @@ + + +ArtemisMessagingServer.networkMapCache - + + + +com.r3corda.node.services.messaging / ArtemisMessagingServer / networkMapCache
+
+

networkMapCache

+ +val networkMapCache: NetworkMapCache
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/-init-.html b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/-init-.html index bdde960be1..d753b6c8dc 100644 --- a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/-init-.html @@ -7,7 +7,7 @@ com.r3corda.node.services.monitor / ClientToServiceCommandMessage / <init>

<init>

-ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand)
+ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand)


diff --git a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/command.html b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/command.html index 7dac045751..6fe85d56d7 100644 --- a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/command.html +++ b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/command.html @@ -8,7 +8,7 @@

command

-val command: ClientToServiceCommand
+val command: ClientToServiceCommand


diff --git a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/index.html b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/index.html index 3bd4f1e53a..986cfe088e 100644 --- a/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/index.html +++ b/docs/build/html/api/com.r3corda.node.services.monitor/-client-to-service-command-message/index.html @@ -17,7 +17,7 @@ <init> -ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand) +ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand) @@ -28,7 +28,7 @@ command -val command: ClientToServiceCommand +val command: ClientToServiceCommand diff --git a/docs/build/html/api/com.r3corda.node.services.monitor/-wallet-monitor-service/index.html b/docs/build/html/api/com.r3corda.node.services.monitor/-wallet-monitor-service/index.html index 160a552453..331b6f14ee 100644 --- a/docs/build/html/api/com.r3corda.node.services.monitor/-wallet-monitor-service/index.html +++ b/docs/build/html/api/com.r3corda.node.services.monitor/-wallet-monitor-service/index.html @@ -36,12 +36,6 @@ additional information while a protocol runs, or confirm an action.

class InputStateRefResolveFailed : Exception - - -PublicKeyLookupFailed - -class PublicKeyLookupFailed : Exception -

Constructors

diff --git a/docs/build/html/api/com.r3corda.node.services.monitor/index.html b/docs/build/html/api/com.r3corda.node.services.monitor/index.html index 1a115e0aab..e2a803d309 100644 --- a/docs/build/html/api/com.r3corda.node.services.monitor/index.html +++ b/docs/build/html/api/com.r3corda.node.services.monitor/index.html @@ -12,13 +12,6 @@ -ClientToServiceCommand - -sealed class ClientToServiceCommand

A command from the monitoring client, to the node.

- - - - ClientToServiceCommandMessage data class ClientToServiceCommandMessage : DirectRequestMessage 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 1463b69b6f..7e75277039 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 @@ -20,23 +20,6 @@ such the hash of a piece of data can be seen as a type of password allowing acce


-

Types

- - - - - - - - - - - -
-NotifyTxRequestMessage -data class NotifyTxRequestMessage : PartyRequestMessage
-NotifyTxResponseMessage -data class NotifyTxResponseMessage

Exceptions

@@ -117,13 +100,6 @@ acknowledgement response with no content, use com.r3corda.core.messa - - - - @@ -137,7 +113,8 @@ acknowledgement response with no content, use com.r3corda.core.messa +fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): Unit

Notify a node of a transaction. Normally any notarisation required would happen before this is called.

+
-NOTIFY_TX_PROTOCOL_TOPIC -val NOTIFY_TX_PROTOCOL_TOPIC: String

Topic for messages notifying a node of a new transaction

-
logger val logger: <ERROR CLASS> notify -fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): <ERROR CLASS><Unit>
diff --git a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending/-service/notify.html b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending/-service/notify.html index d8e9e9d8af..def4890577 100644 --- a/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending/-service/notify.html +++ b/docs/build/html/api/com.r3corda.node.services.persistence/-data-vending/-service/notify.html @@ -8,7 +8,8 @@

notify

-fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): <ERROR CLASS><Unit>
+fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): Unit
+

Notify a node of a transaction. Normally any notarisation required would happen before this is called.



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 bcd3721b90..9beb050839 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 @@ -47,6 +47,14 @@ For any given flow there is only one PSM, even if that protocol invokes subproto +machineId + +val machineId: Long

Unique ID for the deserialized instance protocol state machine. This is NOT maintained across a state machine +being serialized and then deserialized.

+ + + + resultFuture val resultFuture: <ERROR CLASS><R>

This future will complete when the call method returns.

diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/machine-id.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/machine-id.html new file mode 100644 index 0000000000..8c476b3644 --- /dev/null +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/machine-id.html @@ -0,0 +1,21 @@ + + +ProtocolStateMachineImpl.machineId - + + + +com.r3corda.node.services.statemachine / ProtocolStateMachineImpl / machineId
+
+

machineId

+ +val machineId: Long
+Overrides ProtocolStateMachine.machineId
+

Unique ID for the deserialized instance protocol state machine. This is NOT maintained across a state machine +being serialized and then deserialized.

+

Getter
+

Unique ID for this machine, valid only while it is in memory.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/result-future.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/result-future.html index ece81f1303..08aba6f03c 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/result-future.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-protocol-state-machine-impl/result-future.html @@ -9,7 +9,11 @@

resultFuture

val resultFuture: <ERROR CLASS><R>
+Overrides ProtocolStateMachine.resultFuture

This future will complete when the call method returns.

+

Getter
+

This future will complete when the call method returns.

+



diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-init-.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-init-.html index ffb8634883..08ffcd867c 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-init-.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/-init-.html @@ -8,7 +8,7 @@

<init>

StateMachineManager(serviceHub: ServiceHubInternal, tokenizableServices: List<Any>, checkpointStorage: CheckpointStorage, executor: AffinityExecutor)
-

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. +

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.

An implementation of this class will persist state machines to long term storage so they can survive process restarts and, if run with a single-threaded executor, will ensure no two state machines run concurrently with each other diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/add.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/add.html index 479693f411..12baee17bf 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/add.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/add.html @@ -8,7 +8,7 @@

add

-fun <T> add(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>
+fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ProtocolStateMachine<T>

Kicks off a brand new state machine of the given class. It will log with the named logger. The state machine will be persisted when it suspends, with automated restart if the StateMachineManager is restarted with checkpointed state machines in the storage service.

diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/index.html index fc41d464e1..3b80d3d876 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/-state-machine-manager/index.html @@ -8,7 +8,7 @@

StateMachineManager

class StateMachineManager
-

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. +

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.

An implementation of this class will persist state machines to long term storage so they can survive process restarts and, if run with a single-threaded executor, will ensure no two state machines run concurrently with each other @@ -47,7 +47,7 @@ TODO: Implement stub/skel classes that provide a basic RPC framework on top of t <init> -StateMachineManager(serviceHub: ServiceHubInternal, tokenizableServices: List<Any>, checkpointStorage: CheckpointStorage, executor: AffinityExecutor)

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. +StateMachineManager(serviceHub: ServiceHubInternal, tokenizableServices: List<Any>, checkpointStorage: CheckpointStorage, executor: AffinityExecutor)

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.

@@ -103,7 +103,7 @@ which may change across restarts.

add -fun <T> add(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>

Kicks off a brand new state machine of the given class. It will log with the named logger. +fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ProtocolStateMachine<T>

Kicks off a brand new state machine of the given class. It will log with the named logger. The state machine will be persisted when it suspends, with automated restart if the StateMachineManager is restarted with checkpointed state machines in the storage service.

diff --git a/docs/build/html/api/com.r3corda.node.services.statemachine/index.html b/docs/build/html/api/com.r3corda.node.services.statemachine/index.html index d6022f13e7..19e0616c4d 100644 --- a/docs/build/html/api/com.r3corda.node.services.statemachine/index.html +++ b/docs/build/html/api/com.r3corda.node.services.statemachine/index.html @@ -28,7 +28,7 @@ For any given flow there is only one PSM, even if that protocol invokes subproto StateMachineManager -class StateMachineManager

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. +class StateMachineManager

A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects. Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.

diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-init-.html new file mode 100644 index 0000000000..d5767f3db0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-init-.html @@ -0,0 +1,27 @@ + + +BroadcastTransactionProtocol.<init> - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / <init>
+
+

<init>

+BroadcastTransactionProtocol(notarisedTransaction: SignedTransaction, events: Set<ClientToServiceCommand>, participants: Set<Party>)
+

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+

Parameters

+ +notarisedTransaction - transaction which has been notarised (if needed) and is ready to notify nodes about.
+
+ +events - information on the event(s) which triggered the transaction.
+
+ +participants - a list of participants involved in the transaction.
+

Return
+a list of participants who were successfully notified of the transaction.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/-init-.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/-init-.html new file mode 100644 index 0000000000..b2a6ae0ff9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/-init-.html @@ -0,0 +1,14 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage.<init> - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage / <init>
+
+

<init>

+NotifyTxRequestMessage(tx: SignedTransaction, events: Set<ClientToServiceCommand>, replyToParty: Party, sessionID: Long)
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/events.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/events.html new file mode 100644 index 0000000000..b656f71ba9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/events.html @@ -0,0 +1,15 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage.events - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage / events
+
+

events

+ +val events: Set<ClientToServiceCommand>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/index.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/index.html new file mode 100644 index 0000000000..53f50a21d9 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/index.html @@ -0,0 +1,65 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage
+
+

NotifyTxRequestMessage

+data class NotifyTxRequestMessage : PartyRequestMessage
+
+
+

Constructors

+ + + + + + + +
+<init> +NotifyTxRequestMessage(tx: SignedTransaction, events: Set<ClientToServiceCommand>, replyToParty: Party, sessionID: Long)
+

Properties

+ + + + + + + + + + + + + + + + + + + +
+events +val events: Set<ClientToServiceCommand>
+replyToParty +val replyToParty: Party
+sessionID +val sessionID: Long
+tx +val tx: SignedTransaction
+

Inherited Functions

+ + + + + + + +
+getReplyTo +open fun getReplyTo(networkMapCache: NetworkMapCache): MessageRecipients
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/reply-to-party.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/reply-to-party.html new file mode 100644 index 0000000000..9d07de75a2 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/reply-to-party.html @@ -0,0 +1,16 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage.replyToParty - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage / replyToParty
+
+

replyToParty

+ +val replyToParty: Party
+Overrides PartyRequestMessage.replyToParty
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/session-i-d.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/session-i-d.html new file mode 100644 index 0000000000..68128f88ba --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/session-i-d.html @@ -0,0 +1,16 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage.sessionID - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage / sessionID
+
+

sessionID

+ +val sessionID: Long
+Overrides ServiceRequestMessage.sessionID
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/tx.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/tx.html new file mode 100644 index 0000000000..85106b5cf6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-notify-tx-request-message/tx.html @@ -0,0 +1,15 @@ + + +BroadcastTransactionProtocol.NotifyTxRequestMessage.tx - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / NotifyTxRequestMessage / tx
+
+

tx

+ +val tx: SignedTransaction
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-t-o-p-i-c.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-t-o-p-i-c.html new file mode 100644 index 0000000000..ee7538b9e3 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/-t-o-p-i-c.html @@ -0,0 +1,16 @@ + + +BroadcastTransactionProtocol.TOPIC - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / TOPIC
+
+

TOPIC

+ +val TOPIC: String
+

Topic for messages notifying a node of a new transaction

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/call.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/call.html new file mode 100644 index 0000000000..c0ac7a0038 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/call.html @@ -0,0 +1,17 @@ + + +BroadcastTransactionProtocol.call - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / 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/-broadcast-transaction-protocol/events.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/events.html new file mode 100644 index 0000000000..450ae85494 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/events.html @@ -0,0 +1,15 @@ + + +BroadcastTransactionProtocol.events - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / events
+
+

events

+ +val events: Set<ClientToServiceCommand>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/index.html new file mode 100644 index 0000000000..dc0d67c7f0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/index.html @@ -0,0 +1,176 @@ + + +BroadcastTransactionProtocol - + + + +com.r3corda.protocols / BroadcastTransactionProtocol
+
+

BroadcastTransactionProtocol

+class BroadcastTransactionProtocol : ProtocolLogic<Unit>
+

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+

Parameters

+ +notarisedTransaction - transaction which has been notarised (if needed) and is ready to notify nodes about.
+
+ +events - information on the event(s) which triggered the transaction.
+
+ +participants - a list of participants involved in the transaction.
+

Return
+a list of participants who were successfully notified of the transaction.

+
+
+

Types

+ + + + + + + +
+NotifyTxRequestMessage +data class NotifyTxRequestMessage : PartyRequestMessage
+

Constructors

+ + + + + + + +
+<init> +BroadcastTransactionProtocol(notarisedTransaction: SignedTransaction, events: Set<ClientToServiceCommand>, participants: Set<Party>)

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + +
+events +val events: Set<ClientToServiceCommand>
+notarisedTransaction +val notarisedTransaction: SignedTransaction
+participants +val participants: Set<Party>
+topic +val topic: String

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.

+
+

Inherited Properties

+ + + + + + + + + + + + + + + + + + + +
+logger +val logger: <ERROR CLASS>

This is where you should log things to.

+
+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.

+
+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(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+send +fun send(destination: Party, sessionID: Long, payload: Any): Unit
+sendAndReceive +fun <T : Any> sendAndReceive(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 Properties

+ + + + + + + +
+TOPIC +val TOPIC: String

Topic for messages notifying a node of a new transaction

+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/notarised-transaction.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/notarised-transaction.html new file mode 100644 index 0000000000..3cf0eb9250 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/notarised-transaction.html @@ -0,0 +1,15 @@ + + +BroadcastTransactionProtocol.notarisedTransaction - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / notarisedTransaction
+
+

notarisedTransaction

+ +val notarisedTransaction: SignedTransaction
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/participants.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/participants.html new file mode 100644 index 0000000000..52ca155b4d --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/participants.html @@ -0,0 +1,15 @@ + + +BroadcastTransactionProtocol.participants - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / participants
+
+

participants

+ +val participants: Set<Party>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/topic.html b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/topic.html new file mode 100644 index 0000000000..e76d5204cd --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-broadcast-transaction-protocol/topic.html @@ -0,0 +1,18 @@ + + +BroadcastTransactionProtocol.topic - + + + +com.r3corda.protocols / BroadcastTransactionProtocol / topic
+
+

topic

+ +protected val topic: String
+Overrides ProtocolLogic.topic
+

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.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-b-r-o-a-d-c-a-s-t-i-n-g.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-b-r-o-a-d-c-a-s-t-i-n-g.html new file mode 100644 index 0000000000..6bc64f68b6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-b-r-o-a-d-c-a-s-t-i-n-g.html @@ -0,0 +1,42 @@ + + +FinalityProtocol.BROADCASTING - + + + +com.r3corda.protocols / FinalityProtocol / BROADCASTING
+
+

BROADCASTING

+object BROADCASTING : 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/com.r3corda.protocols/-finality-protocol/-init-.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-init-.html new file mode 100644 index 0000000000..f2ccae0920 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-init-.html @@ -0,0 +1,26 @@ + + +FinalityProtocol.<init> - + + + +com.r3corda.protocols / FinalityProtocol / <init>
+
+

<init>

+FinalityProtocol(transaction: SignedTransaction, events: Set<ClientToServiceCommand>, participants: Set<Party>, progressTracker: ProgressTracker = tracker())
+

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+

Parameters

+ +transaction - to commit.
+
+ +events - information on the event(s) which triggered the transaction.
+
+ +participants - a list of participants involved in the transaction.
+

Return
+a list of participants who were successfully notified of the transaction.

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-n-o-t-a-r-i-s-i-n-g.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-n-o-t-a-r-i-s-i-n-g.html new file mode 100644 index 0000000000..107e83f307 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/-n-o-t-a-r-i-s-i-n-g.html @@ -0,0 +1,42 @@ + + +FinalityProtocol.NOTARISING - + + + +com.r3corda.protocols / FinalityProtocol / NOTARISING
+
+

NOTARISING

+object NOTARISING : 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/com.r3corda.protocols/-finality-protocol/call.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/call.html new file mode 100644 index 0000000000..28d95c0021 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/call.html @@ -0,0 +1,17 @@ + + +FinalityProtocol.call - + + + +com.r3corda.protocols / FinalityProtocol / 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/-finality-protocol/events.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/events.html new file mode 100644 index 0000000000..79d78688b6 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/events.html @@ -0,0 +1,15 @@ + + +FinalityProtocol.events - + + + +com.r3corda.protocols / FinalityProtocol / events
+
+

events

+ +val events: Set<ClientToServiceCommand>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/index.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/index.html new file mode 100644 index 0000000000..b67cc77b17 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/index.html @@ -0,0 +1,179 @@ + + +FinalityProtocol - + + + +com.r3corda.protocols / FinalityProtocol
+
+

FinalityProtocol

+class FinalityProtocol : ProtocolLogic<Unit>
+

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+

Parameters

+ +transaction - to commit.
+
+ +events - information on the event(s) which triggered the transaction.
+
+ +participants - a list of participants involved in the transaction.
+

Return
+a list of participants who were successfully notified of the transaction.

+
+
+

Types

+ + + + + + + + + + + +
+BROADCASTING +object BROADCASTING : Step
+NOTARISING +object NOTARISING : Step
+

Constructors

+ + + + + + + +
+<init> +FinalityProtocol(transaction: SignedTransaction, events: Set<ClientToServiceCommand>, participants: Set<Party>, progressTracker: ProgressTracker = tracker())

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+
+

Properties

+ + + + + + + + + + + + + + + + + + + + + + + +
+events +val events: Set<ClientToServiceCommand>
+participants +val participants: Set<Party>
+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.

+
+topic +val topic: String

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.

+
+transaction +val transaction: SignedTransaction
+

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(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+send +fun send(destination: Party, sessionID: Long, payload: Any): Unit
+sendAndReceive +fun <T : Any> sendAndReceive(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
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/participants.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/participants.html new file mode 100644 index 0000000000..261df8a1f0 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/participants.html @@ -0,0 +1,15 @@ + + +FinalityProtocol.participants - + + + +com.r3corda.protocols / FinalityProtocol / participants
+
+

participants

+ +val participants: Set<Party>
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/progress-tracker.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/progress-tracker.html new file mode 100644 index 0000000000..81ba3f4d32 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/progress-tracker.html @@ -0,0 +1,24 @@ + + +FinalityProtocol.progressTracker - + + + +com.r3corda.protocols / FinalityProtocol / 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/-finality-protocol/topic.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/topic.html new file mode 100644 index 0000000000..2733569ace --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/topic.html @@ -0,0 +1,22 @@ + + +FinalityProtocol.topic - + + + +com.r3corda.protocols / FinalityProtocol / topic
+
+

topic

+ +protected val topic: String
+Overrides ProtocolLogic.topic
+

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.

+

Getter
+

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.

+

+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/tracker.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/tracker.html new file mode 100644 index 0000000000..4b042397bb --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/tracker.html @@ -0,0 +1,15 @@ + + +FinalityProtocol.tracker - + + + +com.r3corda.protocols / FinalityProtocol / tracker
+
+

tracker

+ +fun tracker(): ProgressTracker
+
+
+ + diff --git a/docs/build/html/api/com.r3corda.protocols/-finality-protocol/transaction.html b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/transaction.html new file mode 100644 index 0000000000..bfbb47da03 --- /dev/null +++ b/docs/build/html/api/com.r3corda.protocols/-finality-protocol/transaction.html @@ -0,0 +1,15 @@ + + +FinalityProtocol.transaction - + + + +com.r3corda.protocols / FinalityProtocol / transaction
+
+

transaction

+ +val transaction: SignedTransaction
+
+
+ + 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 df625e702a..b850995290 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 @@ -122,8 +122,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> 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 15bfa6662b..4ad6af110c 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 @@ -141,8 +141,8 @@ undo the commit of the input states (the exact mechanism still needs to be worke receive -fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/-party-request-message/index.html b/docs/build/html/api/com.r3corda.protocols/-party-request-message/index.html index f8bac85bdf..c7fe1bb900 100644 --- a/docs/build/html/api/com.r3corda.protocols/-party-request-message/index.html +++ b/docs/build/html/api/com.r3corda.protocols/-party-request-message/index.html @@ -60,7 +60,7 @@ -NotifyTxRequestMessage +NotifyTxRequestMessage data class NotifyTxRequestMessage : PartyRequestMessage 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 f38ba70ea1..c7dab55442 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 @@ -162,8 +162,8 @@ before its sent back to the oracle for signing (for example, adding output state receive -fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> 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 bd3d34d294..11ebedc478 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 @@ -125,8 +125,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> 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 7def52aad4..fb8bf614f2 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 @@ -192,8 +192,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> 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 868d5b687e..eeb06a36ad 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 @@ -156,8 +156,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> 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 0bff42785f..ebacb1b033 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 @@ -150,8 +150,8 @@ access this lazily or from inside receive -fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T>
-fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T> +fun <T : Any> receive(sessionIDForReceive: Long): UntrustworthyData<T>
+fun <T : Any> receive(sessionIDForReceive: Long, receiveType: Class<T>): UntrustworthyData<T> diff --git a/docs/build/html/api/com.r3corda.protocols/index.html b/docs/build/html/api/com.r3corda.protocols/index.html index 786a8b40a5..114f0c7e3b 100644 --- a/docs/build/html/api/com.r3corda.protocols/index.html +++ b/docs/build/html/api/com.r3corda.protocols/index.html @@ -21,6 +21,14 @@ protocols.

+BroadcastTransactionProtocol + +class BroadcastTransactionProtocol : ProtocolLogic<Unit>

Notify all involved parties about a transaction, including storing a copy. Normally this would be called via +FinalityProtocol.

+ + + + DirectRequestMessage interface DirectRequestMessage : ServiceRequestMessage

A message which specifies reply destination as a specific endpoint such as a monitoring client. This is of particular @@ -53,6 +61,13 @@ attachments are saved to local storage automatically.

+FinalityProtocol + +class FinalityProtocol : ProtocolLogic<Unit>

Finalise a transaction by notarising it, then recording it locally, and then sending it to all involved parties.

+ + + + 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 diff --git a/docs/build/html/api/index-outline.html b/docs/build/html/api/index-outline.html index 2620b28499..c01a3b52dd 100644 --- a/docs/build/html/api/index-outline.html +++ b/docs/build/html/api/index-outline.html @@ -91,7 +91,7 @@ -abstract class AbstractConserveAmount<S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>

-abstract class AbstractIssue<in S : ContractState, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>
@@ -391,6 +387,22 @@ +class AllComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
+ interface AllPossibleRecipients : MessageRecipients
class AlwaysSucceedContract : Contract
    @@ -429,6 +441,23 @@
+class AnyComposition<in S : ContractState, C : CommandData, in K : Any> : CompositeClause<S, C, K>
+ data class AppContext
+protected val NETWORK_MAP_ADDRESS: <ERROR CLASS>
+protected data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress
+ +protected data class NodeAddress : SingleMessageRecipient, ArtemisAddress
+ +const val PEERS_PREFIX: String
val config: NodeConfiguration
fun configureWithDevSSLCertificate(): Unit
val directory: Path
protected fun tcpTransport(direction: ConnectionDirection, host: String, port: Int): <ERROR CLASS>
+protected fun toQueueName(target: MessageRecipients): <ERROR CLASS>
+protected fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey?
@@ -539,10 +601,15 @@ -ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>)
+ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>, networkMapCache: NetworkMapCache)
+fun addConnector(hostAndPort: <ERROR CLASS>): <ERROR CLASS>
+fun bridgeExists(name: <ERROR CLASS>): <ERROR CLASS>
+fun bridgeToNetworkMapService(networkMapService: NodeInfo?): Unit
+fun connectorExists(hostAndPort: <ERROR CLASS>): Boolean
+fun deployBridge(hostAndPort: <ERROR CLASS>, name: <ERROR CLASS>): <ERROR CLASS>
val log: <ERROR CLASS>
-val myAddress: SingleMessageRecipient
val myHostPort: <ERROR CLASS>
+val networkMapCache: NetworkMapCache
fun start(): Unit
fun stop(): Unit
@@ -784,6 +851,40 @@ +class BroadcastTransactionProtocol : ProtocolLogic<Unit>
+ open class BusinessCalendar
    @@ -819,7 +920,7 @@
-class Cash : OnLedgerAsset<Currency, State>
+class Cash : OnLedgerAsset<Currency, Commands, State>
-val clauses: <ERROR CLASS>
-val conserveClause: AbstractConserveAmount<State, Currency>
+val conserveClause: AbstractConserveAmount<State, Commands, Currency>
fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Currency>>, owner: PublicKey): TransactionState<State>
-fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
fun generateExitCommand(amount: Amount<Issued<Currency>>): Exit
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: PublicKey, notary: Party): Unit
fun generateIssueCommand(): Issue
fun generateMoveCommand(): Move
val legalContractReference: SecureHash
+fun verify(tx: TransactionForContract): Unit
@@ -1019,7 +1117,7 @@ -interface Clause
+interface Clause<in S : ContractState, C : CommandData, in K : Any>
@@ -1134,7 +1233,7 @@ -sealed class ClientToServiceCommand
+sealed class ClientToServiceCommand
@@ -1201,8 +1297,8 @@ -ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand)
-val command: ClientToServiceCommand
+ClientToServiceCommandMessage(sessionID: Long, replyToRecipient: SingleMessageRecipient, command: ClientToServiceCommand)
+val command: ClientToServiceCommand
val replyToRecipient: SingleMessageRecipient
val sessionID: Long
@@ -1242,21 +1338,7 @@ -abstract class AbstractGroupClause : GroupClause<State, Issued<Terms>>
- -class Group : GroupClauseVerifier<State, Issued<Terms>>
+class Group : GroupClauseVerifier<State, Commands, Issued<Terms>>
-class Issue : AbstractIssue<State, Terms>
+class Issue : AbstractIssue<State, Commands, Terms>
-class Move : AbstractGroupClause
+class Move : ConcreteClause<State, Commands, Issued<Terms>>
-class Redeem : AbstractGroupClause
+class Redeem : ConcreteClause<State, Commands, Issued<Terms>>
@@ -1333,13 +1412,12 @@ -Issue(notary: Party, nonce: Long = random63BitValue())
+Issue(nonce: Long = random63BitValue())
val nonce: Long
-val notary: Party
-class Move : TypeOnlyCommandData, Commands
+data class Move : Move, Commands
-data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands
@@ -1431,7 +1509,7 @@ -data class Issue : Commands
+class Issue : TypeOnlyCommandData, Commands
@@ -1456,7 +1533,7 @@ -data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands
@@ -1486,7 +1562,7 @@ val issuance: PartyAndReference
val maturityDate: Instant
val owner: PublicKey
-val participants: List<PublicKey>
+val participants: <ERROR CLASS>
fun toString(): String
fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): <ERROR CLASS>
fun withIssuance(newIssuance: PartyAndReference): <ERROR CLASS>
@@ -1497,6 +1573,9 @@ +fun generateIssue(issuance: PartyAndReference, 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: Wallet): Unit
val legalContractReference: SecureHash
fun verify(tx: TransactionForContract): Unit
@@ -1510,16 +1589,15 @@ -Commodity(symbol: String, displayName: String, commodityCode: String = symbol, defaultFractionDigits: Int = 0)
+Commodity(commodityCode: String, displayName: String, defaultFractionDigits: Int = 0)
val commodityCode: String
val defaultFractionDigits: Int
val displayName: String
-fun getInstance(symbol: String): Commodity?
-val symbol: String
+fun getInstance(commodityCode: String): Commodity?
-class CommodityContract : OnLedgerAsset<Commodity, State>
+class CommodityContract : OnLedgerAsset<Commodity, Commands, State>
-val clauses: <ERROR CLASS>
-val conserveClause: AbstractConserveAmount<State, Commodity>
+val conserveClause: AbstractConserveAmount<State, Commands, Commodity>
fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Commodity>>, owner: PublicKey): TransactionState<State>
-fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
fun generateExitCommand(amount: Amount<Issued<Commodity>>): Exit
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Commodity>, pennies: Long, owner: PublicKey, notary: Party): Unit
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Commodity>>, owner: PublicKey, notary: Party): Unit
fun generateIssueCommand(): Issue
fun generateMoveCommand(): Move
val legalContractReference: SecureHash
+fun verify(tx: TransactionForContract): Unit
+ + + +abstract class CompositeClause<in S : ContractState, C : CommandData, in K : Any> : Clause<S, C, K>
+ +abstract class ConcreteClause<in S : ContractState, C : CommandData, in T : Any> : Clause<S, C, T>
+ @@ -1819,35 +1924,6 @@ Service(services: ServiceHubInternal)
-val NOTIFY_TX_PROTOCOL_TOPIC: String
-data class NotifyTxRequestMessage : PartyRequestMessage
- -data class NotifyTxResponseMessage
- class TransactionRejectedError : Exception
    @@ -1861,7 +1937,7 @@
val logger: <ERROR CLASS>
-fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): <ERROR CLASS><Unit>
+fun notify(net: MessagingService, myIdentity: Party, recipient: NodeInfo, transaction: SignedTransaction): Unit
val services: ServiceHubInternal
val storage: StorageService
@@ -2155,7 +2231,7 @@ fun registerProcess(process: Process): Unit
fun shutdown(): Unit
fun start(): Unit
-fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>
fun startLocalServer(): Future<ArtemisMessagingServer>
fun startNode(providedName: String?, advertisedServices: Set<ServiceType>): Future<NodeInfo>
fun waitForAllNodesToFinish(): Unit
@@ -2171,7 +2247,7 @@ abstract val networkMapCache: NetworkMapCache
-abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>
abstract fun startLocalServer(): Future<ArtemisMessagingServer>
abstract fun startNode(providedName: String? = null, advertisedServices: Set<ServiceType> = setOf()): Future<NodeInfo>
abstract fun waitForAllNodesToFinish(): Unit
@@ -2313,6 +2389,7 @@ +val clause: Clause<ContractState, CommandData, Unit>
val legalContractReference: SecureHash
fun verify(tx: TransactionForContract): Unit
@@ -2729,6 +2806,45 @@ +class FinalityProtocol : ProtocolLogic<Unit>
+ +class FirstComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
+ data class Fix : CommandData
    @@ -3036,8 +3152,7 @@
-interface GroupClause<in S : ContractState, in T : Any> : Clause, GroupVerify<S, T>
-abstract class GroupClauseVerifier<S : ContractState, T : Any> : SingleClause
+abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any> : ConcreteClause<ContractState, C, Unit>
-interface GroupVerify<in S, in T : Any>
- @@ -3416,25 +3519,6 @@ -class InterceptorClause : SingleClause
- class InterestRateSwap : Contract
    @@ -3462,7 +3546,7 @@
-interface Clause
+interface Clauses
-fun extractCommands(tx: TransactionForContract): Collection<AuthenticatedObject<CommandData>>
fun generateAgreement(floatingLeg: FloatingLeg, fixedLeg: FixedLeg, calculation: Calculation, common: Common, notary: Party): TransactionBuilder
fun generateFix(tx: TransactionBuilder, irs: StateAndRef<State>, fixing: Fix): Unit
val legalContractReference: <ERROR CLASS>
@@ -4101,7 +4179,7 @@ -class ClauseVerifier<S : LinearState> : SingleClause
+class ClauseVerifier<S : LinearState> : ConcreteClause<ContractState, CommandData, Unit>
@@ -4135,20 +4213,6 @@ -enum class MatchBehaviour
- interface Message
    @@ -4533,7 +4597,7 @@
-open class NetClause<P> : SingleClause
+open class NetClause<C : CommandData, P> : ConcreteClause<ContractState, C, Unit>
-open class NoZeroSizedOutputs<in S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>
@@ -5624,7 +5686,7 @@ -class ConserveAmount<P> : AbstractConserveAmount<State<P>, Terms<P>>
+class ConserveAmount<P> : AbstractConserveAmount<State<P>, Commands, Terms<P>>
    @@ -5636,7 +5698,7 @@
-class Group<P> : GroupClauseVerifier<State<P>, Issued<Terms<P>>>
+class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>
-class Issue<P> : AbstractIssue<State<P>, Terms<P>>
+class Issue<P> : AbstractIssue<State<P>, Commands, Terms<P>>
-class Net<P> : NetClause<P>
+class Net<C : CommandData, P> : NetClause<C, P>
-class SetLifecycle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>
-class Settle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>
-class VerifyLifecycle<P> : SingleClause, GroupClause<State<P>, Issued<Terms<P>>>
+class VerifyLifecycle<S : ContractState, C : CommandData, T : Any, P> : ConcreteClause<S, C, T>
@@ -5879,7 +5936,7 @@ fun generateCloseOutNetting(tx: TransactionBuilder, signer: PublicKey, vararg states: State<P>): Unit
-fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, changeKey: PublicKey, assetStates: List<StateAndRef<State<P>>>): PublicKey
+fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, assetStates: List<StateAndRef<State<P>>>): PublicKey
fun generateIssue(tx: TransactionBuilder, obligor: Party, issuanceDef: Terms<P>, pennies: Long, beneficiary: PublicKey, notary: Party): Unit
fun generatePaymentNetting(tx: TransactionBuilder, issued: Issued<Terms<P>>, notary: Party, vararg states: State<P>): Unit
fun generateSetLifecycle(tx: TransactionBuilder, statesAndRefs: List<StateAndRef<State<P>>>, lifecycle: Lifecycle, notary: Party): Unit
@@ -5889,7 +5946,7 @@ -abstract class OnLedgerAsset<T : Any, S : FungibleAsset<T>> : Contract
+abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : Contract
@@ -6393,7 +6448,9 @@ abstract val logger: <ERROR CLASS>
+abstract val machineId: Long
abstract fun <T : Any> receive(topic: String, sessionIDForReceive: Long, recvType: Class<T>): UntrustworthyData<T>
+abstract val resultFuture: <ERROR CLASS><R>
abstract fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
abstract fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T>
abstract val serviceHub: ServiceHub
@@ -6411,6 +6468,7 @@ ProtocolStateMachineImpl(logic: ProtocolLogic<R>, scheduler: <ERROR CLASS>, loggerName: String)
val logger: <ERROR CLASS>
val logic: ProtocolLogic<R>
+val machineId: Long
fun <T : Any> receive(topic: String, sessionIDForReceive: Long, recvType: Class<T>): UntrustworthyData<T>
val resultFuture: <ERROR CLASS><R>
fun run(): R
@@ -7222,34 +7280,7 @@ -abstract class SingleClause : Clause, SingleVerify
- interface SingleMessageRecipient : MessageRecipients
-interface SingleVerify
- data class SingletonSerializationToken : SerializationToken
    @@ -7337,7 +7368,7 @@
-fun <T> add(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>
+fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ProtocolStateMachine<T>
val allStateMachines: List<ProtocolLogic<*>>
val changes: <ERROR CLASS><<ERROR CLASS><ProtocolLogic<*>, AddOrRemove, Long>>
val checkpointStorage: CheckpointStorage
@@ -8806,18 +8837,6 @@ val OUT_EVENT_TOPIC: String
-class PublicKeyLookupFailed : Exception
- val REGISTER_TOPIC: String
data class RegisteredListener
-class Move : TypeOnlyCommandData, Commands
+data class Move : Move, Commands
-data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands
@@ -9602,7 +9603,7 @@ -data class Issue : Commands
+class Issue : TypeOnlyCommandData, Commands
@@ -9627,7 +9627,7 @@ -data class Redeem : Commands
+class Redeem : TypeOnlyCommandData, Commands
@@ -9657,7 +9656,7 @@ val issuance: PartyAndReference
val maturityDate: Instant
val owner: PublicKey
-val participants: List<PublicKey>
+val participants: <ERROR CLASS>
fun toString(): String
fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): <ERROR CLASS>
fun withIssuance(newIssuance: PartyAndReference): <ERROR CLASS>
@@ -9668,6 +9667,9 @@ +fun generateIssue(issuance: PartyAndReference, 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: Wallet): Unit
val legalContractReference: SecureHash
fun verify(tx: TransactionForContract): Unit
@@ -9779,7 +9781,7 @@ -interface Clause
+interface Clauses
-fun extractCommands(tx: TransactionForContract): Collection<AuthenticatedObject<CommandData>>
fun generateAgreement(floatingLeg: FloatingLeg, fixedLeg: FixedLeg, calculation: Calculation, common: Common, notary: Party): TransactionBuilder
fun generateFix(tx: TransactionBuilder, irs: StateAndRef<State>, fixing: Fix): Unit
val legalContractReference: <ERROR CLASS>
@@ -10253,7 +10249,7 @@ val Amount<Currency>.CASH: State
val CASH_PROGRAM_ID: Cash
val COMMODITY_PROGRAM_ID: CommodityContract
-class Cash : OnLedgerAsset<Currency, State>
+class Cash : OnLedgerAsset<Currency, Commands, State>
-val clauses: <ERROR CLASS>
-val conserveClause: AbstractConserveAmount<State, Currency>
+val conserveClause: AbstractConserveAmount<State, Commands, Currency>
fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Currency>>, owner: PublicKey): TransactionState<State>
-fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
fun generateExitCommand(amount: Amount<Issued<Currency>>): Exit
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Currency>, pennies: Long, owner: PublicKey, notary: Party): Unit
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Currency>>, owner: PublicKey, notary: Party): Unit
fun generateIssueCommand(): Issue
fun generateMoveCommand(): Move
val legalContractReference: SecureHash
+fun verify(tx: TransactionForContract): Unit
-class CommodityContract : OnLedgerAsset<Commodity, State>
+class CommodityContract : OnLedgerAsset<Commodity, Commands, State>
-val clauses: <ERROR CLASS>
-val conserveClause: AbstractConserveAmount<State, Commodity>
+val conserveClause: AbstractConserveAmount<State, Commands, Commodity>
fun deriveState(txState: TransactionState<State>, amount: Amount<Issued<Commodity>>, owner: PublicKey): TransactionState<State>
-fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<Commands>>
+fun extractCommands(commands: Collection<AuthenticatedObject<CommandData>>): List<AuthenticatedObject<Commands>>
fun generateExitCommand(amount: Amount<Issued<Commodity>>): Exit
fun generateIssue(tx: TransactionBuilder, tokenDef: Issued<Commodity>, pennies: Long, owner: PublicKey, notary: Party): Unit
fun generateIssue(tx: TransactionBuilder, amount: Amount<Issued<Commodity>>, owner: PublicKey, notary: Party): Unit
fun generateIssueCommand(): Issue
fun generateMoveCommand(): Move
val legalContractReference: SecureHash
+fun verify(tx: TransactionForContract): Unit
@@ -10625,7 +10615,7 @@ -class ConserveAmount<P> : AbstractConserveAmount<State<P>, Terms<P>>
+class ConserveAmount<P> : AbstractConserveAmount<State<P>, Commands, Terms<P>>
    @@ -10637,7 +10627,7 @@
-class Group<P> : GroupClauseVerifier<State<P>, Issued<Terms<P>>>
+class Group<P> : GroupClauseVerifier<State<P>, Commands, Issued<Terms<P>>>
-class Issue<P> : AbstractIssue<State<P>, Terms<P>>
+class Issue<P> : AbstractIssue<State<P>, Commands, Terms<P>>
-class Net<P> : NetClause<P>
+class Net<C : CommandData, P> : NetClause<C, P>
-class SetLifecycle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class SetLifecycle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>
-class Settle<P> : GroupClause<State<P>, Issued<Terms<P>>>
+class Settle<P> : ConcreteClause<State<P>, Commands, Issued<Terms<P>>>
-class VerifyLifecycle<P> : SingleClause, GroupClause<State<P>, Issued<Terms<P>>>
+class VerifyLifecycle<S : ContractState, C : CommandData, T : Any, P> : ConcreteClause<S, C, T>
@@ -10880,7 +10865,7 @@ fun generateCloseOutNetting(tx: TransactionBuilder, signer: PublicKey, vararg states: State<P>): Unit
-fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, changeKey: PublicKey, assetStates: List<StateAndRef<State<P>>>): PublicKey
+fun generateExit(tx: TransactionBuilder, amountIssued: Amount<Issued<Terms<P>>>, assetStates: List<StateAndRef<State<P>>>): PublicKey
fun generateIssue(tx: TransactionBuilder, obligor: Party, issuanceDef: Terms<P>, pennies: Long, beneficiary: PublicKey, notary: Party): Unit
fun generatePaymentNetting(tx: TransactionBuilder, issued: Issued<Terms<P>>, notary: Party, vararg states: State<P>): Unit
fun generateSetLifecycle(tx: TransactionBuilder, statesAndRefs: List<StateAndRef<State<P>>>, lifecycle: Lifecycle, notary: Party): Unit
@@ -10890,7 +10875,7 @@ -abstract class OnLedgerAsset<T : Any, S : FungibleAsset<T>> : Contract
+abstract class OnLedgerAsset<T : Any, C : CommandData, S : FungibleAsset<T>> : Contract
@@ -10965,7 +10948,7 @@ -abstract class AbstractConserveAmount<S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>
-abstract class AbstractIssue<in S : ContractState, T : Any> : GroupClause<S, Issued<T>>
+abstract class AbstractIssue<in S : ContractState, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>
@@ -11027,7 +11006,7 @@ -open class NetClause<P> : SingleClause
+open class NetClause<C : CommandData, P> : ConcreteClause<ContractState, C, Unit>
-open class NoZeroSizedOutputs<in S : FungibleAsset<T>, T : Any> : GroupClause<S, Issued<T>>
+open class NoZeroSizedOutputs<in S : FungibleAsset<T>, C : CommandData, T : Any> : ConcreteClause<S, C, Issued<T>>
@@ -11389,6 +11364,62 @@ val CHF: Currency
+sealed class ClientToServiceCommand
+ data class Command
@@ -11955,7 +11985,7 @@ -class ClauseVerifier<S : LinearState> : SingleClause
+class ClauseVerifier<S : LinearState> : ConcreteClause<ContractState, CommandData, Unit>
@@ -12700,7 +12730,7 @@ -interface Clause
+class AllComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
+class AnyComposition<in S : ContractState, C : CommandData, in K : Any> : CompositeClause<S, C, K>
+ +interface Clause<in S : ContractState, C : CommandData, in K : Any>
+ -interface GroupClause<in S : ContractState, in T : Any> : Clause, GroupVerify<S, T>
-abstract class GroupClauseVerifier<S : ContractState, T : Any> : SingleClause
+abstract class CompositeClause<in S : ContractState, C : CommandData, in K : Any> : Clause<S, C, K>
-interface GroupVerify<in S, in T : Any>
+abstract class ConcreteClause<in S : ContractState, C : CommandData, in T : Any> : Clause<S, C, T>
-class InterceptorClause : SingleClause
+class FirstComposition<S : ContractState, C : CommandData, K : Any> : CompositeClause<S, C, K>
-enum class MatchBehaviour
+abstract class GroupClauseVerifier<S : ContractState, C : CommandData, K : Any> : ConcreteClause<ContractState, C, Unit>
-abstract class SingleClause : Clause, SingleVerify
- -interface SingleVerify
- -fun verifyClauses(tx: TransactionForContract, clauses: List<SingleClause>, commands: Collection<AuthenticatedObject<CommandData>>): Unit
+fun <C : CommandData> Clause<*, C, *>.matches(commands: List<AuthenticatedObject<C>>): Boolean
+fun <C : CommandData> verifyClause(tx: TransactionForContract, clause: Clause<ContractState, C, Unit>, commands: List<AuthenticatedObject<C>>): Unit
@@ -13536,8 +13576,9 @@ -MapChange(node: NodeInfo, type: MapChangeType)
+MapChange(node: NodeInfo, prevNodeInfo: NodeInfo?, type: MapChangeType)
val node: NodeInfo
+val prevNodeInfo: NodeInfo?
val type: MapChangeType
@@ -13551,6 +13592,7 @@ Added
+Modified
Removed
@@ -13986,7 +14028,9 @@ abstract val logger: <ERROR CLASS>
+abstract val machineId: Long
abstract fun <T : Any> receive(topic: String, sessionIDForReceive: Long, recvType: Class<T>): UntrustworthyData<T>
+abstract val resultFuture: <ERROR CLASS><R>
abstract fun send(topic: String, destination: Party, sessionID: Long, payload: Any): Unit
abstract fun <T : Any> sendAndReceive(topic: String, destination: Party, sessionIDForSend: Long, sessionIDForReceive: Long, payload: Any, recvType: Class<T>): UntrustworthyData<T>
abstract val serviceHub: ServiceHub
@@ -14345,6 +14389,7 @@ +val clause: Clause<ContractState, CommandData, Unit>
val legalContractReference: SecureHash
fun verify(tx: TransactionForContract): Unit
@@ -15593,7 +15638,7 @@ fun registerProcess(process: Process): Unit
fun shutdown(): Unit
fun start(): Unit
-fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>
fun startLocalServer(): Future<ArtemisMessagingServer>
fun startNode(providedName: String?, advertisedServices: Set<ServiceType>): Future<NodeInfo>
fun waitForAllNodesToFinish(): Unit
@@ -15609,7 +15654,7 @@ abstract val networkMapCache: NetworkMapCache
-abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>, clientAddress: <ERROR CLASS>?): Future<ArtemisMessagingClient>
+abstract fun startClient(providedName: String, serverAddress: <ERROR CLASS>): Future<ArtemisMessagingClient>
abstract fun startLocalServer(): Future<ArtemisMessagingServer>
abstract fun startNode(providedName: String? = null, advertisedServices: Set<ServiceType> = setOf()): Future<NodeInfo>
abstract fun waitForAllNodesToFinish(): Unit
@@ -16693,7 +16738,7 @@ -ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myHostPort: <ERROR CLASS>, executor: AffinityExecutor)
+ArtemisMessagingClient(directory: Path, config: NodeConfiguration, serverHostPort: <ERROR CLASS>, myIdentity: PublicKey?, executor: AffinityExecutor, persistentInbox: Boolean = true)
data class Handler : MessageHandlerRegistration
@@ -16740,7 +16784,7 @@ ArtemisMessagingComponent(directory: Path, config: NodeConfiguration)
-data class Address : SingleMessageRecipient
+protected interface ArtemisAddress
@@ -16766,10 +16810,44 @@ +protected val NETWORK_MAP_ADDRESS: <ERROR CLASS>
+protected data class NetworkMapAddress : SingleMessageRecipient, ArtemisAddress
+ +protected data class NodeAddress : SingleMessageRecipient, ArtemisAddress
+ +const val PEERS_PREFIX: String
val config: NodeConfiguration
fun configureWithDevSSLCertificate(): Unit
val directory: Path
protected fun tcpTransport(direction: ConnectionDirection, host: String, port: Int): <ERROR CLASS>
+protected fun toQueueName(target: MessageRecipients): <ERROR CLASS>
+protected fun tryParseKeyFromQueueName(queueName: <ERROR CLASS>): PublicKey?
@@ -16781,10 +16859,15 @@ -ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>)
+ArtemisMessagingServer(directory: Path, config: NodeConfiguration, myHostPort: <ERROR CLASS>, networkMapCache: NetworkMapCache)
+fun addConnector(hostAndPort: <ERROR CLASS>): <ERROR CLASS>
+fun bridgeExists(name: <ERROR CLASS>): <ERROR CLASS>
+fun bridgeToNetworkMapService(networkMapService: NodeInfo?): Unit
+fun connectorExists(hostAndPort: <ERROR CLASS>): Boolean
+fun deployBridge(hostAndPort: <ERROR CLASS>, name: <ERROR CLASS>): <ERROR CLASS>
val log: <ERROR CLASS>
-val myAddress: SingleMessageRecipient
val myHostPort: <ERROR CLASS>
+val networkMapCache: NetworkMapCache
fun start(): Unit
fun stop(): Unit
@@ -16801,65 +16884,6 @@ -sealed class ClientToServiceCommand
- data class ClientToServiceCommandMessage : DirectRequestMessage
val OUT_EVENT_TOPIC: String
-class PublicKeyLookupFailed : Exception
- val REGISTER_TOPIC: String
data class RegisteredListener
-fun <T> add(loggerName: String, logic: ProtocolLogic<T>): <ERROR CLASS><T>
+fun <T> add(loggerName: String, logic: ProtocolLogic<T>): ProtocolStateMachine<T>
val allStateMachines: List<ProtocolLogic<*>>
val changes: <ERROR CLASS><<ERROR CLASS><ProtocolLogic<*>, AddOrRemove, Long>>
val checkpointStorage: CheckpointStorage
@@ -18468,6 +18452,40 @@ +class BroadcastTransactionProtocol : ProtocolLogic<Unit>
+ interface DirectRequestMessage : ServiceRequestMessage
    @@ -18599,6 +18617,27 @@
+class FinalityProtocol : ProtocolLogic<Unit>
+ object NotaryChangeProtocol : AbstractStateReplacementProtocol<Party>
    diff --git a/docs/build/html/consensus.html b/docs/build/html/consensus.html index b54a936efd..7becca68d2 100644 --- a/docs/build/html/consensus.html +++ b/docs/build/html/consensus.html @@ -102,12 +102,13 @@
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -186,7 +187,7 @@

    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. +

    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:

    /**
      * A wrapper for [ContractState] containing additional platform-level state information.
    @@ -235,25 +236,52 @@ 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.

    +

    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).

    -
    -
    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).

    +

    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, or perform timestamping and notarisation at the same time, which is the chosen behaviour for this model.

    +

    There will never be exact clock synchronisation between the party creating the transaction and the notary. +This is not only due to physics, network latencies etc but because between inserting the command and getting the +notary to sign there may be many other steps, like sending the transaction to other parties involved in the trade +as well, or even requesting human signoff. Thus the time observed by the notary may be quite different to the +time observed in step 1.

    +

    For this reason, times in transactions are specified as time windows, not absolute times. Time windows can be +open-ended, i.e. specify only one of “before” and “after” or they can be fully bounded. If a time window needs to +be converted to an absolute time for e.g. display purposes, there is a utility method on Timestamp to +calculate the mid point - but in a distributed system there can never be “true time”, only an approximation of it.

    +

    In this way we express that the true value of the fact “the current time” is actually unknowable. Even when both before and +after times are included, the transaction could have occurred at any point between those two timestamps. Here +“occurrence” could mean the execution date, the value date, the trade date etc ... the notary doesn’t care what precise +meaning the timestamp has to the contract.

    +

    By creating a range that can be either closed or open at one end, we allow all of the following facts to be modelled:

    +
      +
    • This transaction occurred at some point after the given time (e.g. after a maturity event)
    • +
    • This transaction occurred at any time before the given time (e.g. before a bankruptcy event)
    • +
    • This transaction occurred at some point roughly around the given time (e.g. on a specific day)
    • +
    +
    +

    Note

    +

    It is assumed that the time feed for a notary is GPS/NaviStar time as defined by the atomic +clocks at the US Naval Observatory. This time feed is extremely accurate and available globally for free.

    +

    Running a Notary Service

    @@ -262,13 +290,27 @@ or perform timestamping and notarisation at the same time, which is the
  • 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:

    +

    Once a transaction is built and ready to be finalised, normally you would call FinalityProtocol passing in a +SignedTransaction (including signatures from the participants) and a list of participants to notify. This requests a +notary signature if needed, and then sends a copy of the notarised transaction to all participants for them to store. +FinalityProtocol delegates to NotaryProtocol.Client followed by BroadcastTransactionProtocol to do the +actual work of notarising and broadcasting the transaction. For example:

    +
    fun finaliseTransaction(serviceHub: ServiceHubInternal, ptx: TransactionBuilder, participants: Set<Party>)
    +        : ListenableFuture<Unit> {
    +    // We conclusively cannot have all the signatures, as the notary has not signed yet
    +    val tx = ptx.toSignedTransaction(checkSufficientSignatures = false)
    +    // The empty set would be the trigger events, which are not used here
    +    val protocol = FinalityProtocol(tx, emptySet(), participants)
    +    return serviceHub.startProtocol("protocol.finalisation", protocol)
    +}
    +
    +
    +

    To manually obtain a signature from a notary you can call NotaryProtocol.Client directly. 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))
     }
    @@ -304,6 +346,10 @@ For example, the following snippet can be used when writing a custom protocol:Obtain the old notary signature
     
  • Record and distribute the final transaction to the participants so that everyone possesses the new state
  • +
    +

    Note

    +

    Eventually this will be handled automatically on demand.

    +
    diff --git a/docs/build/html/contract-catalogue.html b/docs/build/html/contract-catalogue.html index c2e49454ee..19f8b8a7df 100644 --- a/docs/build/html/contract-catalogue.html +++ b/docs/build/html/contract-catalogue.html @@ -8,7 +8,7 @@ - Platform contracts — R3 Corda latest documentation + Contract catalogue — R3 Corda latest documentation @@ -93,13 +93,15 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

      -
    • Platform contracts
        +
      • Contract catalogue
        • Cash
        • +
        • Commodity
        • Commercial Paper
        • Interest Rate Swap
        • Obligation
        • @@ -155,7 +157,7 @@
          • Docs »
          • -
          • Platform contracts
          • +
          • Contract catalogue
          • @@ -169,8 +171,8 @@
            -
            -

            Platform contracts

            +
            +

            Contract catalogue

            There are a number of contracts supplied with Corda, which cover both core functionality (such as cash on ledger) and provide examples of how to model complex contracts (such as interest rate swaps). There is also a Dummy contract. However it does not provide any meaningful functionality, and is intended purely for testing purposes.

            @@ -184,6 +186,14 @@ contracts as part of settlement of an outstanding debt. The contracts’ ver objects of the correct value are received by the beneficiary as part of the settlement transaction.

            The cash contract supports issuing, moving and exiting (destroying) states. Note, however, that issuance cannot be part of the same transaction as other cash commands, in order to minimise complexity in balance verification.

            +

            Cash shares a common superclass, OnChainAsset, with the Commodity contract. This implements common behaviour of +assets which can be issued, moved and exited on chain, with the subclasses handling asset-specific data types and +behaviour.

            +
            +
            +

            Commodity

            +

            The Commodity contract is an early stage example of a non-currency contract whose states implement the FungibleAsset +interface. This is used as a proof of concept for non-cash obligations.

            Commercial Paper

            diff --git a/docs/build/html/creating-a-cordapp.html b/docs/build/html/creating-a-cordapp.html new file mode 100644 index 0000000000..ecb8d7fdad --- /dev/null +++ b/docs/build/html/creating-a-cordapp.html @@ -0,0 +1,302 @@ + + + + + + + + + + + Creating a Cordapp — R3 Corda latest documentation + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
            + + + + +
            + + + + + + +
            +
            + + + + + + +
            + +
            +
            +
            +
            + +
            +

            Creating a Cordapp

            +

            A Cordapp is an application that runs on the Corda platform using the platform APIs and plugin system. They are self +contained in separate JARs from the node server JAR that are created and distributed.

            +
            +

            App Plugins

            +
            +

            Note

            +

            Currently apps are only supported for JVM languages.

            +
            +

            To create an app plugin you must you must extend from CordaPluginRegistry. The JavaDoc contains +specific details of the implementation, but you can extend the server in the following ways:

            +
              +
            1. Required protocols: Specify which protocols will be whitelisted for use in your web APIs.
            2. +
            3. Service plugins: Register your services.
            4. +
            5. Web APIs: You may register your own endpoints under /api/ of the built-in web server.
            6. +
            7. Static web endpoints: You may register your own static serving directories for serving web content.
            8. +
            +
            +
            +

            Services

            +

            Services are classes which are constructed after the node has started. It is provided a ServiceHubInternal which +allows a richer API than the ServiceHub exposed to contracts. It enables adding protocols, registering +message handlers and more. The service does not run in a separate thread, so the only entry point to the service is during +construction, where message handlers should be registered and threads started.

            +
            +
            +

            Starting Nodes

            +

            To use an app you must also have a node server. To create a node server run the gradle installTemplateNodes task.

            +

            This will output the node JAR to build/libs/corda.jar and several sample/standard +node setups to build/nodes. For now you can use the build/nodes/nodea configuration as a template.

            +

            Each node server must have a node.conf file in the same directory as the node JAR file. After first +execution of the node server there will be many other configuration and persistence files created in this directory.

            +
            +

            Note

            +

            Outside of development environments do not store your node directories in the build folder.

            +
            +
            +
            +

            Installing Apps

            +

            Once you have created your app JAR you can install it to a node by adding it to <node_dir>/plugins/. In this +case the node_dir is the location where your node server’s JAR and configuration file is.

            +
            +

            Note

            +

            If the directory does not exist you can create it manually.

            +
            +
            +
            +

            Starting your Node

            +

            Now you have a node server with your app installed, you can run it by navigating to <node_dir> and running

            +
            +
            java -jar corda.jar
            +

            The plugin should automatically be registered and the configuration file used.

            +
            +

            Warning

            +

            If your working directory is not <node_dir> your plugins and configuration will not be used.

            +
            +
            +
            + + +
            +
            + + +
            +
            + +
            + +
            + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/build/html/data-model.html b/docs/build/html/data-model.html index 579c5cfdc5..0fe9086620 100644 --- a/docs/build/html/data-model.html +++ b/docs/build/html/data-model.html @@ -102,12 +102,13 @@
          • Data types
          • Consensus model
          • Networking and messaging
          • +
          • Creating a Cordapp
          • Running the demos
          • Node administration

          Contracts

          Tutorials

          @@ -175,11 +176,11 @@

          Data model

          This article covers the data model: how states, transactions and code contracts interact with each other and -how they are represented in the code. It doesn’t attempt to give detailed design rationales or information on future +how they are represented in software. It doesn’t attempt to give detailed design rationales or information on future design elements: please refer to the R3 wiki for background information.

          Overview

          -

          We begin with the idea of a global ledger. In our model, although the ledger is shared, it is not always the case that +

          We begin with the idea of a global ledger. In our model although the ledger is shared, it is not always the case that transactions and ledger entries are globally visible. In cases where a set of transactions stays within a small subgroup of users it should be possible to keep the relevant data purely within that group.

          To ensure consistency in a global, shared system where not all data may be visible to all participants, we rely @@ -190,34 +191,58 @@ consume/destroy, these are called inputs, and contains a set of

          States contain arbitrary data, but they always contain at minimum a hash of the bytecode of a contract code file, which is a program expressed in JVM byte code that runs sandboxed inside a Java virtual machine. Contract code (or just “contracts” in the rest of this document) are globally shared pieces of business logic.

          +
          +

          Note

          +

          In the current code dynamic loading of contracts is not implemented, so states currently point at +statically created object instances. This will change in the near future.

          +

          Contracts define a verify function, which is a pure function given the entire transaction as input. To be considered valid, the transaction must be accepted by the verify function of every contract pointed to by the input and output states.

          Beyond inputs and outputs, transactions may also contain commands, small data packets that -the platform does not interpret itself, but which can parameterise execution of the contracts. They can be thought of as +the platform does not interpret itself but which can parameterise execution of the contracts. They can be thought of as arguments to the verify function. Each command has a list of public keys associated with it. The platform ensures that the transaction is signed by every key listed in the commands before the contracts start to execute. Thus, a verify function can trust that all listed keys have signed the transaction but is responsible for verifying that any keys required for the transaction to be valid from the verify function’s perspective are included in the list. Public keys may be random/identityless for privacy, or linked to a well known legal identity, for example via a public key infrastructure (PKI).

          +
          +

          Note

          +

          Linkage of keys with identities via a PKI is only partially implemented in the current code.

          +

          Commands are always embedded inside a transaction. Sometimes, there’s a larger piece of data that can be reused across many different transactions. For this use case, we have attachments. Every transaction can refer to zero or more -attachments by hash. Attachments are always ZIP/JAR files, which may contain arbitrary content. Contract code can then -access the attachments by opening them as a JarInputStream (this is temporary and will change later).

          +attachments by hash. Attachments are always ZIP/JAR files, which may contain arbitrary content. These files are +then exposed on the classpath and so can be opened by contract code in the same manner as any JAR resources +would be loaded.

          +
          +

          Note

          +

          Attachments must be opened explicitly in the current code.

          +

          Note that there is nothing that explicitly binds together specific inputs, outputs, commands or attachments. Instead it’s up to the contract code to interpret the pieces inside the transaction and ensure they fit together correctly. This is done to maximise flexibility for the contract developer.

          Transactions may sometimes need to provide a contract with data from the outside world. Examples may include stock prices, facts about events or the statuses of legal entities (e.g. bankruptcy), and so on. The providers of such facts are called oracles and they provide facts to the ledger by signing transactions that contain commands they -recognise, or by creating signed attachments. The commands contain the fact and the signature shows agreement to that fact. -Time is also modelled as a fact, with the signature of a special kind of oracle called a timestamping authority (TSA). -A TSA signs a transaction if a pre-defined timestamping command in it defines a after/before time window that includes -“true time” (i.e. GPS time as calibrated to the US Naval Observatory). An oracle may prefer to generate a signed -attachment if the fact it’s creating is relatively static and may be referred to over and over again.

          +recognise, or by creating signed attachments. The commands contain the fact and the signature shows agreement to that fact.

          +

          Time is also modelled as a fact, with the signature of a special kind of service called a notary. A notary is +a (very likely) decentralised service which fulfils the role that miners play in other blockchain systems: +notaries ensure only one transaction can consume any given output. Additionally they may verify a timestamping +command placed inside the transaction, which specifies a time window in which the transaction is considered +valid for notarisation. The time window can be open ended (i.e. with a start but no end or vice versa). In this +way transactions can be linked to the notary’s clock.

          +

          It is possible for a single Corda network to have multiple competing notaries. Each state points to the notary that +controls it. Whilst a single transaction may only consume states if they are all controlled by the same notary, +a special type of transaction is provided that moves a state (or set of states) from one notary to another.

          +
          +

          Note

          +

          Currently the platform code will not re-assign states to a single notary as needed for you, in case of +a mismatch. This is a future planned feature.

          +

          As the same terminology often crops up in different distributed ledger designs, let’s compare this to other -distributed ledger systems you may be familiar with. You can find more detailed design rationales for why the platform +systems you may be familiar with. You can find more detailed design rationales for why the platform differs from existing systems in the R3 wiki, but to summarise, the driving factors are:

            @@ -225,7 +250,7 @@ but to summarise, the driving factors are:

          • Improved scalability vs Ethereum, as well as ability to keep parts of the transaction graph private (yet still uniquely addressable)
          • No reliance on proof of work
          • Re-use of existing sandboxing virtual machines
          • -
          • Use of type safe GCd implementation languages.
          • +
          • Use of type safe GCd implementation languages
          • Simplified auditing
          @@ -240,8 +265,11 @@ as the unspent transaction output set (UTXO set) as a result. Given the same transaction, a contract’s accept function always yields exactly the same result.
        • Bitcoin output scripts are parameterised by the input scripts in the spending transaction. This is somewhat similar to our notion of a command.
        • +
        • Bitcoin has a global distributed notary service; that’s the famous block chain. However, there is only one. Whilst +there is a notion of a “side chain”, this isn’t integrated with the core Bitcoin data model and thus adds large +amounts of additional complexity meaning in practice side chains are not used.
        • Bitcoin transactions, like ours, refer to the states they consume by using a (txhash, index) pair. The Bitcoin -protocol calls these “outpoints”. In our prototype code they are known as StateRefs but the concept is identical.
        • +protocol calls these “outpoints”. In our code they are known as StateRefs but the concept is identical.
        • Bitcoin transactions have an associated timestamp (the time at which they are mined).

        Differences:

        @@ -255,8 +283,8 @@ this has proved limiting. Our transactions invoke not only input contracts but a
      • A Bitcoin script can only be given a fixed set of byte arrays as the input. This means there’s no way for a contract to examine the structure of the entire transaction, which severely limits what contracts can do.
      • Our contracts are Turing-complete and can be written in any ordinary programming language that targets the JVM.
      • -
      • Our transactions and contracts have to get their time from an attached timestamp rather than a block chain. This is -important given that we are currently considering block-free conflict resolution algorithms.
      • +
      • Our transactions and contracts get their time from an attached timestamp rather than a block. This is +important given that we use block-free conflict resolution algorithms. The timestamp can be arbitrarily precise.
      • We use the term “contract” to refer to a bundle of business logic that may handle various different tasks, beyond transaction verification. For instance, currently our contracts also include code for creating valid transactions (this is often called “wallet code” in Bitcoin).
      • @@ -397,9 +425,8 @@ although not due to lack of practicality.

        to “reshape” outputs to useful/standardised sizes, for example, and to send outputs of complex transactions back to their issuers for reissuance to “sever” long privacy-breaching chains.

        Finally, it should be noted that some of the issues described here are not really “cons” of -the UTXO model; they’re just fundamental. -If you used many different anonymous accounts to preserve some privacy and then needed to -spend the contents of them all simultaneously, you’d hit the same problem, so it’s not +the UTXO model; they’re just fundamental. If you used many different anonymous accounts to preserve some privacy +and then needed to spend the contents of them all simultaneously, you’d hit the same problem, so it’s not something that can be trivially fixed with data model changes.

    diff --git a/docs/build/html/event-scheduling.html b/docs/build/html/event-scheduling.html index ae8ae72d1c..e70ba56646 100644 --- a/docs/build/html/event-scheduling.html +++ b/docs/build/html/event-scheduling.html @@ -93,12 +93,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -171,7 +172,7 @@

    Event scheduling

    -

    This article explains our experimental approach to modelling time based events in code. It explains how a contract +

    This article explains our 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

    @@ -189,7 +190,7 @@ event is thus a property of the current contract state. By next, we mean earlie 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, +place when this event occurs. We already have a model for business processes in the form of protocols, 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.

    @@ -202,12 +203,11 @@ to do so, then nothing will be scheduled.

    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. +wallet, it can expect to be queried for the next activity when committed to the wallet.
  • 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.
  • +The important thing to remember is that in the current implementation, each node that is party to the transaction +will execute the same ProtocolLogic, so it needs to establish roles in the business process based on the contract +state and the node it is running on. Each side will follow different but complementary paths through the business logic.

    Note

    @@ -219,19 +219,19 @@ handler to help with obtaining a unqiue and secure random session. An example i

    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.

    +ScheduledActivity object returned. Be aware that this only happens if the wallet considers the state +“relevant”, for instance, because the owner of the node also owns that state. States that your node happens to +encounter but which aren’t related to yourself will not have any activities scheduled.

    An example

    -

    Let’s take an example of the Interest Rate Swap fixings for our scheduled events. The first task is to implement the +

    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.

    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)
    @@ -249,9 +249,9 @@ rate swap State i
     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.

    +

    This is a way to create a reference to the ProtocolLogic class and its constructor parameters to +instantiate. The reference 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 diff --git a/docs/build/html/genindex.html b/docs/build/html/genindex.html index f1dff760e2..e4eee46938 100644 --- a/docs/build/html/genindex.html +++ b/docs/build/html/genindex.html @@ -92,12 +92,13 @@

  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    diff --git a/docs/build/html/index.html b/docs/build/html/index.html index cc236dc946..ee6a8ee7c9 100644 --- a/docs/build/html/index.html +++ b/docs/build/html/index.html @@ -92,12 +92,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -164,6 +165,11 @@

    Welcome to the Corda repository!

    +
    +

    Warning

    +

    This build of the docs is from the master branch, not a milestone release. It may not reflect the +current state of the code.

    +

    This documentation describes Corda, a proposed architecture for distributed ledgers, the vision for which is outlined in the Corda Introductory Whitepaper.

    The goal of this prototype is to explore fundamentally better designs for distributed ledgers than what presently exists on the market, tailor made for the needs of the financial industry. We are attempting to prove or disprove the @@ -182,7 +188,6 @@ following hypothesis:

    Overview

    • What’s included?
    • @@ -204,10 +209,12 @@ following hypothesis:

    • Data types
    • Consensus model
        @@ -221,12 +228,18 @@ following hypothesis:

    • Networking and messaging
    • +
    • Creating a Cordapp +
    • Running the demos
      • Trader demo
      • IRS demo
      • @@ -244,8 +257,9 @@ following hypothesis:

        Contracts

          -
        • Platform contracts
        • Writing a contract test
        • Writing oracle services
        • Event scheduling
            diff --git a/docs/build/html/inthebox.html b/docs/build/html/inthebox.html index 20ef17eddb..49be3e61e0 100644 --- a/docs/build/html/inthebox.html +++ b/docs/build/html/inthebox.html @@ -88,7 +88,6 @@

            Overview

            Contracts

            Tutorials

            @@ -170,72 +170,30 @@

            What’s included?

            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.

              -
            • +
                +
              • A peer to peer network with message persistence and delivery retries.
              • +
              • Key data structures for defining contracts and states.
              • +
              • Smart contracts, which you can find in the Contract catalogue.
              • +
              • 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, and a web app demo that uses it to present a frontend for IRS trading.

              Some things it does not currently include but should gain later are:

              • Sandboxing, distribution or publication of smart contract code
              • -
              • Database persistence
              • A user interface for administration
              • -
              • Many other things

              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 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.
              • +
              • There’s currently no permissioning framework.
              • +
              • Some privacy techniques aren’t implemented yet.
              • +
              • It uses an embedded SQL database and doesn’t yet have connectivity support for mainstream SQL vendors (Oracle, +Postgres, MySQL, SQL Server etc).
              -
              -

              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 -four contracts in the repository:

              -
                -
              1. Cash
              2. -
              3. Commercial paper
              4. -
              5. Nettable obligations
              6. -
              7. Interest rate swaps
              8. -
              -

              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 -the issuing party for internal bookkeeping purposes.

              -

              Cash states are fungible with each other (can be merged and split arbitrarily) if they use the same currency, -party and deposit reference.

              -

              CommercialPaper implements an asset with a face value denominated in a certain currency, which may be redeemed at -the issuing party after a certain time. Commercial paper states define the face value (e.g. $1000) and the time -at which they may be redeemed. The contract allows the paper to be issued, traded and redeemed. The commercial paper -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 irs

              -

              Obligation implements a bilaterally or multi-laterally nettable, fungible obligation that can default.

              -

              Each contract comes with unit tests.

              -

              Kotlin

              Corda is written in a language called Kotlin. Kotlin is a language that targets the JVM diff --git a/docs/build/html/messaging.html b/docs/build/html/messaging.html index 3d5eb87b77..ac2122b265 100644 --- a/docs/build/html/messaging.html +++ b/docs/build/html/messaging.html @@ -31,7 +31,7 @@ - + @@ -93,18 +93,17 @@

            • Data types
            • Consensus model
            • Networking and messaging
            • +
            • Creating a Cordapp
            • Running the demos
            • Node administration

            Contracts

            Tutorials

            @@ -171,111 +170,47 @@

            Networking and messaging

            -

            Although the platform does not currently provide a network backend, some preliminary interfaces are defined along with -an in-memory implementation provided for use by unit tests and other exploratory code. An implementation based on Apache -Kafka is also being developed, which should be sufficient for real use cases to be implemented in the short run, even -though in the long run a fully peer to peer protocol will be required.

            -

            This article quickly explains the basic networking interfaces in the code.

            -
            -

            Messaging vs networking

            -

            It is important to understand that the code expects any networking module to provide the following services:

            -
              -
            • Persistent, reliable and secure delivery of complete messages. The module is expected to retry delivery if initial -attempts fail.
            • -
            • Ability to send messages both 1:1 and 1:many, where ‘many’ may mean the entire group of network users.
            • -
            -

            The details of how this is achieved are not exposed to the rest of the code.

            -
            -
            -

            Interfaces

            -

            The most important interface is called MessagingService and is defined in the core/messaging/Messaging.kt file. -It declares an interface with the following operations:

            -
              -
            • addMessageHandler(topic: String, executor: Executor, callback: (Message, MessageHandlerRegistration) -> Unit)
            • -
            • createMessage(topic: String, data: ByteArray): Message
            • -
            • send(message: Message, targetRecipients: MessageRecipients)
            • -
            • stop()
            • -
            -

            along with a few misc others that are not important enough to discuss here.

            -

            A topic is simply a string that identifies the kind of message that is being sent. When a message is received, the -topic is compared exactly to the list of registered message handlers and if it matches, the callback is invoked. -Adding a handler returns a MessageHandlerRegistration object that can be used to remove the handler, and that -registration object is also passed to each invocation to simplify the case where a handler wishes to remove itself.

            -

            Some helper functions are also provided that simplify the process of sending a message by using Kryo serialisation, and -registering one-shot handlers that remove themselves once they finished running, but those don’t need to be implemented -by network module authors themselves.

            -

            Destinations are represented using opaque classes (i.e. their contents are defined by the implementation). The -MessageRecipients interface represents any possible set of recipients: it’s used when a piece of code doesn’t -care who is going to get a message, just that someone does. The SingleMessageRecipient interface inherits from -MessageRecipients and represents a handle to some specific individual receiver on the network. Whether they are -identified by IP address, public key, message router ID or some other kind of address is not exposed at this level. -MessageRecipientGroup is not used anywhere at the moment but represents multiple simultaneous recipients. And -finally AllPossibleRecipients is used for network wide broadcast. It’s also unused right now, outside of unit tests.

            -
            -
            -

            In memory implementation

            -

            To ease unit testing of business logic, a simple in-memory messaging service is provided. To access this you can inherit -your test case class from the TestWithInMemoryNetwork class. This provides a few utility methods to help test -code that involves message passing.

            -

            You can run a mock network session in one of two modes:

            -
              -
            • Manually “pumped”
            • -
            • Automatically pumped with background threads
            • -
            -

            “Pumping” is the act of telling a mock network node to pop a message off its queue and process it. Typically you want -unit tests to be fast, repeatable and you want to be able to insert your own changes into the middle of any given -message sequence. This is what the manual mode is for. In this mode, all logic runs on the same thread (the thread -running the unit tests). You can create and use a node like this:

            -
            -
            val (aliceAddr, aliceNode) = makeNode(inBackground = false)
            -val (bobAddr, bobNode) = makeNode(false)
            -
            -aliceNode.send("test.topic", aliceAddr, "foo")
            -bobNode.pump(blocking = false)
            -
            -
            -
            +

            Corda uses AMQP/1.0 over TLS between nodes which is currently implemented using Apache Artemis, an embeddable message +queue broker. Building on established MQ protocols gives us features like persistence to disk, automatic delivery +retries with backoff and dead-letter routing, security, large message streaming and so on.

            +

            Artemis is hidden behind a thin interface that also has an in-memory only implementation suitable for use in +unit tests and visualisation tools.

            Note

            -

            Currently only Kotlin examples are available for networking and protocol state machines. Java examples may -follow later. Naming arguments in Kotlin like above is optional but sometimes useful to make code examples clearer.

            +

            A future version of Corda will allow the MQ broker to be split out of the main node and run as a +separate server. We may also support non-Artemis implementations via JMS, allowing the broker to be swapped +out for alternative implementations.

            -

            The above code won’t actually do anything because no message handler is registered for “test.topic” so the message will -go into a holding area. If/when we add a handler that can accept test.topic, the message will be delivered then.

            -

            Sometimes you don’t want to have to call the pump method over and over again. You can use the runNetwork { .. } -construct to fix this: any code inside the block will be run, and then all nodes you created will be pumped over and -over until all of them have reported that they have no work left to do. This means any ping-pongs of messages will -be run until everything settles.

            -

            You can see more examples of how to use this in the file InMemoryMessagingTests.kt.

            -

            If you specify inBackground = true to makeNode then each node will create its own background thread which will -sit around waiting for messages to be delivered. Handlers will then be invoked on that background thread. This is a -more difficult style of programming that can be used to increase the realism of the unit tests by ensuring multiple -nodes run in parallel, just as they would on a real network spread over multiple machines.

            +

            There are multiple ways of interacting with the network. When writing an application you typically won’t use the +messaging subsystem directly. Instead you will build on top of the protocol framework, +which adds a layer on top of raw messaging to manage multi-step protocols and let you think in terms of identities +rather than specific network endpoints.

            +
            +

            Messaging types

            +

            Every Message object has an associated topic and may have a session ID. These are wrapped in a TopicSession. +An implementation of MessagingService can be used to create messages and send them. You can get access to the +messaging service via the ServiceHub object that is provided to your app. Endpoints on the network are +identified at the lowest level using SingleMessageRecipient which may be e.g. an IP address, or in future +versions perhaps a routing path through the network.

            Network Map Service

            -

            Supporting the messaging layer is a network map service, which is responsible for tracking public nodes on the network. -Nodes have an internal component, the network map cache, which contains a copy of the network map. When a node starts up -its cache fetches a copy of the full network map, and requests to be notified of changes. The node then registers itself -with the network map service, and the service notifies subscribers that a new node has joined the network. Nodes do not -automatically deregister themselves, so (for example) nodes going offline briefly for maintenance are retained in the -network map, and messages for them will be queued, minimising disruption.

            -

            Nodes submit signed changes to the map service, which then forwards them on to nodes which have requested to be notified -of changes. This process achieves basic consensus of the overall network map, although currently it has no formal -process for identifying or recovering from issues such as network outages. Later versions are planned to address this.

            -

            Registration change notifications contain a serial number, which indicates their relative ordering, similar to the -serial number on DNS records. These numbers must increase with each change, but are not expected to be sequential. -Changes are then signed by the party whom the node represents to confirm the association between party and node. -The change, signature and public key are then sent to the network map service, which verifies the signature and then -updates the network map accordingly.

            -

            The network map cache currently supports:

            +

            Supporting the messaging layer is a network map service, which is responsible for tracking public nodes on the network.

            +

            Nodes have an internal component, the network map cache, which contains a copy of the network map (which is just a +document). When a node starts up its cache fetches a copy of the full network map, and requests to be notified of +changes. The node then registers itself with the network map service, and the service notifies subscribers that a new +node has joined the network. Nodes do not automatically deregister themselves, so (for example) nodes going offline +briefly for maintenance are retained in the network map, and messages for them will be queued, minimising disruption.

            +

            Nodes submit signed changes to the map service, which then forwards update notifications on to nodes which have +requested to be notified of changes.

            +

            The network map currently supports:

            • Looking up nodes by service
            • Looking up node for a party
            • -
            • Suggesting a node providing a specific service, based on suitability for a contract and parties, for example suggesting
            • +
            • Suggesting a node providing a specific service, based on suitability for a contract and parties, for example suggesting +an appropriate interest rates oracle for a interest rate swap contract. Currently no recommendation logic is in place. +The code simply picks the first registered node that supports the required service.
            -

            an appropriate interest rates oracle for a interest rate swap contract. Currently no recommendation logic is in place -(the code simply picks the first registered node that supports the required service), however.

            @@ -286,7 +221,7 @@ updates the network map accordingly.

          Contracts

          Tutorials

          @@ -111,9 +112,8 @@
        • Writing oracle services
        • Event scheduling
        • @@ -175,12 +175,8 @@

          Writing oracle services

          This article covers oracles: network services that link the ledger to the outside world by providing facts that affect the validity of transactions.

          -

          The current prototype includes two oracles:

          -
            -
          1. A timestamping service
          2. -
          3. An interest rate fixing service
          4. -
          -

          We will examine the similarities and differences in their design, whilst covering how the oracle concept works.

          +

          The current prototype includes an example oracle that provides an interest rate fixing service. It is used by the +IRS trading demo app.

          Introduction

          Oracles are a key concept in the block chain/decentralised ledger space. They can be essential for many kinds of @@ -212,10 +208,14 @@ consensus (breaks).

          When a fact is encoded in a command, it is embedded in the transaction itself. The oracle then acts as a co-signer to the entire transaction. The oracle’s signature is valid only for that transaction, and thus even if a fact (like a stock price) does not change, every transaction that incorporates that fact must go back to the oracle for signing.

          -

          When a fact is encoded as an attachment, it is a separate object to the transaction which is referred to by hash. +

          When a fact is encoded as an attachment, it is a separate object to the transaction and is referred to by hash. Nodes download attachments from peers at the same time as they download transactions, unless of course the node has already seen that attachment, in which case it won’t fetch it again. Contracts have access to the contents of -attachments and attachments can be digitally signed (in future).

          +attachments when they run.

          +
          +

          Note

          +

          Currently attachments do not support digital signing, but this is a planned feature.

          +

          As you can see, both approaches share a few things: they both allow arbitrary binary data to be provided to transactions (and thus contracts). The primary difference is whether the data is a freely reusable, standalone object or whether it’s integrated with a transaction.

          @@ -232,71 +232,33 @@ attachment. attachment.
        -
        -

        Asserting continuously varying data that is publicly known

        -

        Let’s look at the timestamping oracle that can be found in the TimestamperService class. This is an example of -an oracle that uses a command because the current time is a constantly changing fact that everybody knows.

        -

        The most obvious way to implement such a service would be:

        -
          -
        1. The creator of the transaction that depends on the time reads their local clock
        2. -
        3. They insert a command with that time into the transaction
        4. -
        5. They then send it to the oracle for signing.
        6. -
        -

        But this approach has a problem. There will never be exact clock synchronisation between the party creating the -transaction and the oracle. This is not only due to physics, network latencies etc but because between inserting the -command and getting the oracle to sign there may be many other steps, like sending the transaction to other parties -involved in the trade as well, or even requesting human signoff. Thus the time observed by the oracle may be quite -different to the time observed in step 1. This problem can occur any time an oracle attests to a constantly changing -value.

        +
        +

        Asserting continuously varying data

        Note

        -

        It is assumed that “true time” for a timestamping oracle means GPS/NaviStar time as defined by the atomic -clocks at the US Naval Observatory. This time feed is extremely accurate and available globally for free.

        +

        A future version of the platform will include a complete tutorial on implementing this type of oracle.

        -

        We fix it by including explicit tolerances in the command, which is defined like this:

        -
        data class TimestampCommand(val after: Instant?, val before: Instant?) : CommandData
        -    init {
        -        if (after == null && before == null)
        -            throw IllegalArgumentException("At least one of before/after must be specified")
        -        if (after != null && before != null)
        -            check(after <= before)
        -    }
        -}
        -
        -
        -

        This defines a class that has two optional fields: before and after, along with a constructor that imposes a couple -more constraints that cannot be expressed in the type system, namely, that “after” actually is temporally after -“before”, and that at least one bound must be present. A timestamp command that doesn’t contain anything is illegal.

        -

        Thus we express that the true value of the fact “the current time” is actually unknowable. Even when both before and -after times are included, the transaction could have occurred at any point between those two timestamps. In this case -“occurrence” could mean the execution date, the value date, the trade date etc ... the oracle doesn’t care what precise -meaning the timestamp has to the contract.

        -

        By creating a range that can be either closed or open at one end, we allow all of the following facts to be modelled:

        -
          -
        • This transaction occurred at some point after the given time (e.g. after a maturity event)
        • -
        • This transaction occurred at any time before the given time (e.g. before a bankruptcy event)
        • -
        • This transaction occurred at some point roughly around the given time (e.g. on a specific day)
        • -
        +

        Let’s look at the interest rates oracle that can be found in the NodeInterestRates file. This is an example of +an oracle that uses a command because the current interest rate fix is a constantly changing fact.

        +

        The obvious way to implement such a service is like this:

        +
          +
        1. The creator of the transaction that depends on the interest rate sends it to the oracle.
        2. +
        3. The oracle inserts a command with the rate and signs the transaction.
        4. +
        5. The oracle sends it back.
        6. +
        +

        But this has a problem - it would mean that the oracle has to be the first entity to sign the transaction, which might impose +ordering constraints we don’t want to deal with (being able to get all parties to sign in parallel is a very nice thing). +So the way we actually implement it is like this:

        +
          +
        1. The creator of the transaction that depends on the interest rate asks for the current rate. They can abort at this point +if they want to.
        2. +
        3. They insert a command with that rate and the time it was obtained into the transaction.
        4. +
        5. They then send it to the oracle for signing, along with everyone else in parallel. The oracle checks that the command +has correct data for the asserted time, and signs if so.
        6. +

        This same technique can be adapted to other types of oracle.

        -
        -
        -

        Asserting occasionally varying data that is not publicly known

        -

        Sometimes you may want a fact that changes, but is not entirely continuous. Additionally the exact value may not be -public, or may only be semi-public (e.g. easily available to some entities on the network but not all). An example of -this would be a LIBOR interest rate fix.

        -

        In this case, the following design can be used. The oracle service provides a query API which returns the current value, -and a signing service that signs a transaction if the data in the command matches the answer being returned by the -query API. Probably the query response contains some sort of timestamp as well, so the service can recognise values -that were true in the past but no longer are (this is arguably a part of the fact being asserted).

        -

        Because the signature covers the transaction, and transactions may end up being forwarded anywhere, the fact itself -is independently checkable. However, this approach can be useful when the data itself costs money, because the act -of issuing the signature in the first place can be charged for (e.g. by requiring the submission of a fresh -Cash.State that has been re-assigned to a key owned by the oracle service). Because the signature covers the -transaction and not only the fact, this allows for a kind of weak pseudo-DRM over data feeds. Whilst a smart -contract could in theory include a transaction parsing and signature checking library, writing a contract in this way -would be conclusive evidence of intent to disobey the rules of the service (res ipsa loquitur). In an environment -where parties are legally identifiable, usage of such a contract would by itself be sufficient to trigger some sort of -punishment.

        +

        The oracle consists of a core class that implements the query/sign operations (for easy unit testing), and then a separate +class that binds it to the network layer.

        Here is an extract from the NodeService.Oracle class and supporting types:

        /** A [FixOf] identifies the question side of a fix: what day, tenor and type of fix ("LIBOR", "EURIBOR" etc) */
         data class FixOf(val name: String, val forDay: LocalDate, val ofTenor: Duration)
        @@ -314,21 +276,17 @@ punishment.

        Because the fix contains a timestamp (the forDay field), there can be an arbitrary delay between a fix being requested via query and the signature being requested via sign.

        -
        -

        Implementing oracles in the framework

        -

        Implementation involves the following steps:

        -
          -
        1. Defining a high level oracle class, that exposes the basic API operations.
        2. -
        3. Defining a lower level service class, that binds network messages to the API.
        4. -
        5. Defining a protocol using the Protocol state machines framework to make it easy for a client to interact -with the oracle.
        6. -
        7. Constructing it (when advertised) in AbstractNode.
        8. -
        -

        An example of how to do this can be found in the NodeInterestRates.Oracle, NodeInterestRates.Service and -RateFixProtocol classes.

        -

        The exact details of how this code works will change in future, so for now consulting the protocols tutorial and the -code for the server-side oracles implementation will have to suffice. There will be more detail added once the -platform APIs have settled down.

        +
        +

        Pay-per-play oracles

        +

        Because the signature covers the transaction, and transactions may end up being forwarded anywhere, the fact itself +is independently checkable. However, this approach can still be useful when the data itself costs money, because the act +of issuing the signature in the first place can be charged for (e.g. by requiring the submission of a fresh +Cash.State that has been re-assigned to a key owned by the oracle service). Because the signature covers the +transaction and not only the fact, this allows for a kind of weak pseudo-DRM over data feeds. Whilst a smart +contract could in theory include a transaction parsing and signature checking library, writing a contract in this way +would be conclusive evidence of intent to disobey the rules of the service (res ipsa loquitur). In an environment +where parties are legally identifiable, usage of such a contract would by itself be sufficient to trigger some sort of +punishment.

        diff --git a/docs/build/html/protocol-state-machines.html b/docs/build/html/protocol-state-machines.html index 12894998fc..bc95028831 100644 --- a/docs/build/html/protocol-state-machines.html +++ b/docs/build/html/protocol-state-machines.html @@ -93,12 +93,13 @@
      • Data types
      • Consensus model
      • Networking and messaging
      • +
      • Creating a Cordapp
      • Running the demos
      • Node administration

      Contracts

      Tutorials

      @@ -111,12 +112,15 @@
    • Introduction
    • Theory
    • A two party trading protocol
    • -
    • Suspendable methods
    • -
    • The state machine manager
    • +
    • Suspendable functions
    • +
    • Starting your protocol
    • Implementing the seller
    • +
    • Subprotocols
    • Implementing the buyer
    • Progress tracking
    • Unit testing
    • +
    • Versioning
    • +
    • Future features
  • Writing oracle services
  • @@ -258,24 +262,18 @@ represents an atomic asset swap.

    We start by defining a wrapper that namespaces the protocol code, two functions to start either the buy or sell side of the protocol, and two classes that will contain the protocol definition. We also pick what data will be used by each side.

    +
    +

    Note

    +

    The code samples in this tutorial are only available in Kotlin, but you can use any JVM language to +write them and the approach is the same.

    +
    object TwoPartyTradeProtocol {
    -    val TRADE_TOPIC = "platform.trade"
    +    val TOPIC = "platform.trade"
     
    -    fun runSeller(smm: StateMachineManager, timestampingAuthority: LegallyIdentifiableNode,
    -                  otherSide: SingleMessageRecipient, assetToSell: StateAndRef<OwnableState>, price: Amount,
    -                  myKeyPair: KeyPair, buyerSessionID: Long): ListenableFuture<SignedTransaction> {
    -        val seller = Seller(otherSide, timestampingAuthority, assetToSell, price, myKeyPair, buyerSessionID)
    -        smm.add("$TRADE_TOPIC.seller", seller)
    -        return seller.resultFuture
    -    }
    -
    -    fun runBuyer(smm: StateMachineManager, timestampingAuthority: LegallyIdentifiableNode,
    -                 otherSide: SingleMessageRecipient, acceptablePrice: Amount, typeToBuy: Class<out OwnableState>,
    -                 sessionID: Long): ListenableFuture<SignedTransaction> {
    -        val buyer = Buyer(otherSide, timestampingAuthority.identity, acceptablePrice, typeToBuy, sessionID)
    -        smm.add("$TRADE_TOPIC.buyer", buyer)
    -        return buyer.resultFuture
    +    class UnacceptablePriceException(val givenPrice: Amount<Currency>) : Exception("Unacceptable price: $givenPrice")
    +    class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() {
    +        override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName"
         }
     
         // This object is serialised to the network and is the first protocol message the seller sends to the buyer.
    @@ -288,28 +286,24 @@ each side.

    class SignaturesFromSeller(val timestampAuthoritySig: DigitalSignature.WithKey, val sellerSig: DigitalSignature.WithKey) - class Seller(val otherSide: SingleMessageRecipient, - val timestampingAuthority: LegallyIdentifiableNode, - val assetToSell: StateAndRef<OwnableState>, - val price: Amount, - val myKeyPair: KeyPair, - val buyerSessionID: Long) : ProtocolLogic<SignedTransaction>() { + open class Seller(val otherSide: Party, + val notaryNode: NodeInfo, + val assetToSell: StateAndRef<OwnableState>, + val price: Amount<Currency>, + val myKeyPair: KeyPair, + val buyerSessionID: Long, + override val progressTracker: ProgressTracker = Seller.tracker()) : ProtocolLogic<SignedTransaction>() { @Suspendable override fun call(): SignedTransaction { TODO() } } - class UnacceptablePriceException(val givenPrice: Amount) : Exception() - class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() { - override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName" - } - - class Buyer(val otherSide: SingleMessageRecipient, - val timestampingAuthority: Party, - val acceptablePrice: Amount, - val typeToBuy: Class<out OwnableState>, - val sessionID: Long) : ProtocolLogic<SignedTransaction>() { + open class Buyer(val otherSide: Party, + val notary: Party, + val acceptablePrice: Amount<Currency>, + val typeToBuy: Class<out OwnableState>, + val sessionID: Long) : ProtocolLogic<SignedTransaction>() { @Suspendable override fun call(): SignedTransaction { TODO() @@ -321,51 +315,42 @@ each side.

    Let’s unpack what this code does:

      -
    • It defines a several classes nested inside the main TwoPartyTradeProtocol singleton, and a couple of methods, one -to run the buyer side of the protocol and one to run the seller side. Some of the classes are simply protocol messages.
    • +
    • It defines a several classes nested inside the main TwoPartyTradeProtocol singleton. Some of the classes +are simply protocol messages or exceptions. The other two represent the buyer and seller side of the protocol.
    • It defines the “trade topic”, which is just a string that namespaces this protocol. The prefix “platform.” is reserved -by the DLG, but you can define your own protocols using standard Java-style reverse DNS notation.
    • -
    • The runBuyer and runSeller methods take a number of parameters that specialise the protocol for this run, -use them to construct a Buyer or Seller object respectively, and then add the new instances to the -StateMachineManager. The purpose of this class is described below. The smm.add method takes a logger name as -the first parameter, this is just a standard JDK logging identifier string, and the instance to add.
    • +by Corda, but you can define your own protocol namespaces using standard Java-style reverse DNS notation.

    Going through the data needed to become a seller, we have:

      -
    • timestampingAuthority: LegallyIdentifiableNode - a reference to a node on the P2P network that acts as a trusted -timestamper. The use of timestamping is described in Data model.
    • otherSide: SingleMessageRecipient - the network address of the node with which you are trading.
    • +
    • notaryNode: NodeInfo - the entry in the network map for the chosen notary. See “Consensus model” for more +information on notaries.
    • assetToSell: StateAndRef<OwnableState> - a pointer to the ledger entry that represents the thing being sold.
    • -
    • price: Amount - the agreed on price that the asset is being sold for.
    • +
    • price: Amount<Currency> - the agreed on price that the asset is being sold for (without an issuer constraint).
    • myKeyPair: KeyPair - the key pair that controls the asset being sold. It will be used to sign the transaction.
    • buyerSessionID: Long - a unique number that identifies this trade to the buyer. It is expected that the buyer -knows that the trade is going to take place and has sent you such a number already. (This field may go away in a future -iteration of the framework)
    • +knows that the trade is going to take place and has sent you such a number already.

    Note

    -

    Session IDs keep different traffic streams separated, so for security they must be large and random enough -to be unguessable. 63 bits is good enough.

    +

    Session IDs will be automatically handled in a future version of the framework.

    And for the buyer:

      -
    • acceptablePrice: Amount - the price that was agreed upon out of band. If the seller specifies a price less than -or equal to this, then the trade will go ahead.
    • +
    • acceptablePrice: Amount<Currency> - the price that was agreed upon out of band. If the seller specifies +a price less than or equal to this, then the trade will go ahead.
    • typeToBuy: Class<out OwnableState> - the type of state that is being purchased. This is used to check that the sell side of the protocol isn’t trying to sell us the wrong thing, whether by accident or on purpose.
    • sessionID: Long - the session ID that was handed to the seller in order to start the protocol.
    -

    The run methods return a ListenableFuture that will complete when the protocol has finished.

    -

    Alright, so using this protocol shouldn’t be too hard: in the simplest case we can just pass in the details of the trade -to either runBuyer or runSeller, depending on who we are, and then call .get() on resulting object to -block the calling thread until the protocol has finished. Or we could register a callback on the returned future that -will be invoked when it’s done, where we could e.g. update a user interface.

    -

    Finally, we define a couple of exceptions, and two classes that will be used as a protocol message called -SellerTradeInfo and SignaturesFromSeller.

    +

    Alright, so using this protocol shouldn’t be too hard: in the simplest case we can just create a Buyer or Seller +with the details of the trade, depending on who we are. We then have to start the protocol in some way. Just +calling the call function ourselves won’t work: instead we need to ask the framework to start the protocol for +us. More on that in a moment.

    -
    -

    Suspendable methods

    -

    The call method of the buyer/seller classes is marked with the @Suspendable annotation. What does this mean?

    +
    +

    Suspendable functions

    +

    The call function of the buyer/seller classes is marked with the @Suspendable annotation. What does this mean?

    As mentioned above, our protocol framework will at points suspend the code and serialise it to disk. For this to work, any methods on the call stack must have been pre-marked as @Suspendable so the bytecode rewriter knows to modify the underlying code to support this new feature. A protocol is suspended when calling either receive, send or @@ -375,85 +360,73 @@ get a useful error message telling you which methods you didn’t mark. The and try again.

    Note

    -

    A future version of Java is likely to remove this pre-marking requirement completely.

    +

    Java 9 is likely to remove this pre-marking requirement completely.

    -
    -

    The state machine manager

    -

    The SMM is a class responsible for taking care of all running protocols in a node. It knows how to register handlers -with a MessagingService and iterate the right state machine when messages arrive. It provides the -send/receive/sendAndReceive calls that let the code request network interaction and it will store a serialised copy of -each state machine before it’s suspended to wait for the network.

    -

    To get a StateMachineManager, you currently have to build one by passing in a ServiceHub and a thread or thread -pool which it can use. This will change in future so don’t worry about the details of this too much: just check the -unit tests to see how it’s done.

    +
    +

    Starting your protocol

    +

    The StateMachineManager is the class responsible for taking care of all running protocols in a node. It knows +how to register handlers with the messaging system (see “Networking and messaging”) and iterate the right state machine +when messages arrive. It provides the send/receive/sendAndReceive calls that let the code request network +interaction and it will save/restore serialised versions of the fiber at the right times.

    +

    Protocols can be invoked in several ways. For instance, they can be triggered by scheduled events, +see “Event scheduling” to learn more about this. Or they can be triggered via the HTTP API. Or they can +be triggered directly via the Java-level node APIs from your app code.

    +

    You request a protocol to be invoked by using the ServiceHub.invokeProtocolAsync method. This takes a +Java reflection Class object that describes the protocol class to use (in this case, either Buyer or Seller). +It also takes a set of arguments to pass to the constructor. Because it’s possible for protocol invocations to +be requested by untrusted code (e.g. a state that you have been sent), the types that can be passed into the +protocol are checked against a whitelist, which can be extended by apps themselves at load time.

    +

    The process of starting a protocol returns a ListenableFuture that you can use to either block waiting for +the result, or register a callback that will be invoked when the result is ready.

    Implementing the seller

    -

    Let’s implement the Seller.call method. This will be invoked by the platform when the protocol is started by the -StateMachineManager.

    +

    Let’s implement the Seller.call method. This will be run when the protocol is invoked.

    -
    val partialTX: SignedTransaction = receiveAndCheckProposedTransaction()
    -
    -// These two steps could be done in parallel, in theory. Our framework doesn't support that yet though.
    -val ourSignature = signWithOurKey(partialTX)
    -val tsaSig = subProtocol(TimestampingProtocol(timestampingAuthority, partialTX.txBits))
    -
    -val stx: SignedTransaction = sendSignatures(partialTX, ourSignature, tsaSig)
    -
    -return stx
    +
    @Suspendable
    +override fun call(): SignedTransaction {
    +    val partialTX: SignedTransaction = receiveAndCheckProposedTransaction()
    +    val ourSignature: DigitalSignature.WithKey = signWithOurKey(partialTX)
    +    val notarySignature = getNotarySignature(partialTX)
    +    val result: SignedTransaction = sendSignatures(partialTX, ourSignature, notarySignature)
    +    return result
    +}
     

    Here we see the outline of the procedure. We receive a proposed trade transaction from the buyer and check that it’s -valid. Then we sign with our own key, request a timestamping authority to assert with another signature that the -timestamp in the transaction (if any) is valid, and finally we send back both our signature and the TSA’s signature. -Finally, we hand back to the code that invoked the protocol the finished transaction in a couple of different forms.

    -
    -

    Note

    -

    ProtocolLogic classes can be composed together. Here, we see the use of the subProtocol method, which -is given an instance of TimestampingProtocol. This protocol will run to completion and yield a result, almost -as if it’s a regular method call. In fact, under the hood, all the subProtocol method does is pass the current -fiber object into the newly created object and then run call() on it ... so it basically _is_ just a method call. -This is where we can see the benefits of using continuations/fibers as a programming model.

    -
    +valid. Then we sign with our own key and request a notary to assert with another signature that the +timestamp in the transaction (if any) is valid and there are no double spends, and send back both +our signature and the notaries signature. Finally, we hand back to the code that invoked the protocol the +finished transaction.

    Let’s fill out the receiveAndCheckProposedTransaction() method.

    @Suspendable
    -open fun receiveAndCheckProposedTransaction(): SignedTransaction {
    +private fun receiveAndCheckProposedTransaction(): SignedTransaction {
         val sessionID = random63BitValue()
     
         // Make the first message we'll send to kick off the protocol.
         val hello = SellerTradeInfo(assetToSell, price, myKeyPair.public, sessionID)
     
    -    val maybeSTX = sendAndReceive<SignedTransaction>(TRADE_TOPIC, otherSide, buyerSessionID, sessionID, hello)
    +    val maybeSTX = sendAndReceive<SignedTransaction>(otherSide, buyerSessionID, sessionID, hello)
     
         maybeSTX.validate {
             // Check that the tx proposed by the buyer is valid.
    -        val missingSigs = it.verify(throwIfSignaturesAreMissing = false)
    -        if (missingSigs != setOf(myKeyPair.public, timestampingAuthority.identity.owningKey))
    -            throw SignatureException("The set of missing signatures is not as expected: $missingSigs")
    +        val missingSigs: Set<PublicKey> = it.verifySignatures(throwIfSignaturesAreMissing = false)
    +        val expected = setOf(myKeyPair.public, notaryNode.identity.owningKey)
    +        if (missingSigs != expected)
    +            throw SignatureException("The set of missing signatures is not as expected: ${missingSigs.toStringsShort()} vs ${expected.toStringsShort()}")
     
             val wtx: WireTransaction = it.tx
             logger.trace { "Received partially signed transaction: ${it.id}" }
     
    -        checkDependencies(it)
    +        // Download and check all the things that this transaction depends on and verify it is contract-valid,
    +        // even though it is missing signatures.
    +        subProtocol(ResolveTransactionsProtocol(wtx, otherSide))
     
    -        // This verifies that the transaction is contract-valid, even though it is missing signatures.
    -        serviceHub.verifyTransaction(wtx.toLedgerTransaction(serviceHub.identityService))
    -
    -        if (wtx.outputs.sumCashBy(myKeyPair.public) != price)
    -            throw IllegalArgumentException("Transaction is not sending us the right amounnt of cash")
    -
    -        // There are all sorts of funny games a malicious secondary might play here, we should fix them:
    -        //
    -        // - This tx may attempt to send some assets we aren't intending to sell to the secondary, if
    -        //   we're reusing keys! So don't reuse keys!
    -        // - This tx may include output states that impose odd conditions on the movement of the cash,
    -        //   once we implement state pairing.
    -        //
    -        // but the goal of this code is not to be fully secure (yet), but rather, just to find good ways to
    -        // express protocol state machines on top of the messaging layer.
    +        if (wtx.outputs.map { it.data }.sumCashBy(myKeyPair.public).withoutIssuer() != price)
    +            throw IllegalArgumentException("Transaction is not sending us the right amount of cash")
     
             return it
         }
    @@ -461,48 +434,66 @@ This is where we can see the benefits of using continuations/fibers as a program
     
    -

    That’s pretty straightforward. We generate a session ID to identify what’s happening on the seller side, fill out +

    Let’s break this down. We generate a session ID to identify what’s happening on the seller side, fill out the initial protocol message, and then call sendAndReceive. This function takes a few arguments:

    • The topic string that ensures the message is routed to the right bit of code in the other side’s node.
    • The session IDs that ensure the messages don’t get mixed up with other simultaneous trades.
    • The thing to send. It’ll be serialised and sent automatically.
    • -
    • Finally a type argument, which is the kind of object we’re expecting to receive from the other side.
    • +
    • Finally a type argument, which is the kind of object we’re expecting to receive from the other side. If we get +back something else an exception is thrown.
    -

    Once sendAndReceive is called, the call method will be suspended into a continuation. When it gets back we’ll do a log -message. The buyer is supposed to send us a transaction with all the right inputs/outputs/commands in return, with their -cash put into the transaction and their signature on it authorising the movement of the cash.

    +

    Once sendAndReceive is called, the call method will be suspended into a continuation and saved to persistent +storage. If the node crashes or is restarted, the protocol will effectively continue as if nothing had happened. Your +code may remain blocked inside such a call for seconds, minutes, hours or even days in the case of a protocol that +needs human interaction!

    Note

    There are a couple of rules you need to bear in mind when writing a class that will be used as a continuation. The first is that anything on the stack when the function is suspended will be stored into the heap and kept alive by the garbage collector. So try to avoid keeping enormous data structures alive unless you really have to.

    -

    The second is that as well as being kept on the heap, objects reachable from the stack will be serialised. The state +

    The second is that as well as being kept on the heap, objects reachable from the stack will be serialised. The state of the function call may be resurrected much later! Kryo doesn’t require objects be marked as serialisable, but even so, doing things like creating threads from inside these calls would be a bad idea. They should only contain business -logic.

    +logic and only do I/O via the methods exposed by the protocol framework.

    +

    It’s OK to keep references around to many large internal node services though: these will be serialised using a +special token that’s recognised by the platform, and wired up to the right instance when the continuation is +loaded off disk again.

    +

    The buyer is supposed to send us a transaction with all the right inputs/outputs/commands in response to the opening +message, with their cash put into the transaction and their signature on it authorising the movement of the cash.

    You get back a simple wrapper class, UntrustworthyData<SignedTransaction>, which is just a marker class that reminds us that the data came from a potentially malicious external source and may have been tampered with or be unexpected in -other ways. It doesn’t add any functionality, but acts as a reminder to “scrub” the data before use. Here, our scrubbing -simply involves checking the signatures on it. Then we go ahead and check all the dependencies of this partial -transaction for validity. Here’s the code to do that:

    +other ways. It doesn’t add any functionality, but acts as a reminder to “scrub” the data before use.

    +

    Our “scrubbing” has three parts:

    +
      +
    1. Check that the expected signatures are present and correct. At this point we expect our own signature to be missing, +because of course we didn’t sign it yet, and also the signature of the notary because that must always come last.
    2. +
    3. We resolve the transaction, which we will cover below.
    4. +
    5. We verify that the transaction is paying us the demanded price.
    6. +
    +
    +
    +

    Subprotocols

    +

    Protocols can be composed via nesting. Invoking a sub-protocol looks similar to an ordinary function call:

    @Suspendable
    -private fun checkDependencies(stx: SignedTransaction) {
    -    // Download and check all the transactions that this transaction depends on, but do not check this
    -    // transaction itself.
    -    val dependencyTxIDs = stx.tx.inputs.map { it.txhash }.toSet()
    -    subProtocol(ResolveTransactionsProtocol(dependencyTxIDs, otherSide))
    +private fun getNotarySignature(stx: SignedTransaction): DigitalSignature.LegallyIdentifiable {
    +    progressTracker.currentStep = NOTARY
    +    return subProtocol(NotaryProtocol.Client(stx))
     }
     
    -

    This is simple enough: we mark the method as @Suspendable because we’re going to invoke a sub-protocol, extract the -IDs of the transactions the proposed transaction depends on, and then uses a protocol provided by the system to download -and check them all. This protocol does a breadth-first search over the dependency graph, bottoming out at issuance -transactions that don’t have any inputs themselves. Once the node has audited the transaction history, all the dependencies -are committed to the node’s local database so they won’t be checked again next time.

    +

    In this code snippet we are using the NotaryProtocol.Client to request notarisation of the transaction. +We simply create the protocol object via its constructor, and then pass it to the subProtocol method which +returns the result of the protocol’s execution directly. Behind the scenes all this is doing is wiring up progress +tracking (discussed more below) and then running the objects call method. Because this little helper method can +be on the stack when network IO takes place, we mark it as @Suspendable.

    +

    Going back to the previous code snippet, we use a subprotocol called ResolveTransactionsProtocol. This is +responsible for downloading and checking all the dependencies of a transaction, which in Corda are always retrievable +from the party that sent you a transaction that uses them. This protocol returns a list of LedgerTransaction +objects, but we don’t need them here so we just ignore the return value.

    Note

    Transaction dependency resolution assumes that the peer you got the transaction from has all of the @@ -518,26 +509,28 @@ well (but having handled the fact that some signatures are missing ourselves).

    open fun signWithOurKey(partialTX: SignedTransaction) = myKeyPair.signWithECDSA(partialTX.txBits)
     
     @Suspendable
    -open fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey,
    -                        tsaSig: DigitalSignature.LegallyIdentifiable): SignedTransaction {
    -    val fullySigned = partialTX + tsaSig + ourSignature
    -
    +private fun sendSignatures(partialTX: SignedTransaction, ourSignature: DigitalSignature.WithKey,
    +                           notarySignature: DigitalSignature.LegallyIdentifiable): SignedTransaction {
    +    val fullySigned = partialTX + ourSignature + notarySignature
         logger.trace { "Built finished transaction, sending back to secondary!" }
    -
    -    send(TRADE_TOPIC, otherSide, buyerSessionID, SignaturesFromSeller(tsaSig, ourSignature))
    +    send(otherSide, buyerSessionID, SignaturesFromSeller(ourSignature, notarySignature))
         return fullySigned
     }
     
    -

    It’s should be all pretty straightforward: here, txBits is the raw byte array representing the transaction.

    -

    In sendSignatures, we take the two signatures we calculated, then add them to the partial transaction we were sent. -We provide an overload for the + operator so signatures can be added to a SignedTransaction easily. Finally, we wrap the +

    It’s all pretty straightforward from now on. Here txBits is the raw byte array representing the serialised +transaction, and we just use our private key to calculate a signature over it. As a reminder, in Corda signatures do +not cover other signatures: just the core of the transaction data.

    +

    In sendSignatures, we take the two signatures we obtained and add them to the partial transaction we were sent. +There is an overload for the + operator so signatures can be added to a SignedTransaction easily. Finally, we wrap the two signatures in a simple wrapper message class and send it back. The send won’t block waiting for an acknowledgement, but the underlying message queue software will retry delivery if the other side has gone away temporarily.

    +

    You can also see that every protocol instance has a logger (using the SLF4J API) which you can use to log progress +messages.

    Warning

    -

    This code is not secure. Other than not checking for all possible invalid constructions, if the +

    This sample code is not secure. Other than not checking for all possible invalid constructions, if the seller stops before sending the finalised transaction to the buyer, the seller is left with a valid transaction but the buyer isn’t, so they can’t spend the asset they just purchased! This sort of thing will be fixed in a future version of the code.

    @@ -552,24 +545,25 @@ override fun call(): SignedTransaction { val tradeRequest = receiveAndValidateTradeRequest() val (ptx, cashSigningPubKeys) = assembleSharedTX(tradeRequest) val stx = signWithOurKeys(cashSigningPubKeys, ptx) + val signatures = swapSignaturesWithSeller(stx, tradeRequest.sessionID) - logger.trace { "Got signatures from seller, verifying ... "} - val fullySigned = stx + signatures.timestampAuthoritySig + signatures.sellerSig - fullySigned.verify() + logger.trace { "Got signatures from seller, verifying ... " } - logger.trace { "Fully signed transaction was valid. Trade complete! :-)" } + val fullySigned = stx + signatures.sellerSig + signatures.notarySig + fullySigned.verifySignatures() + + logger.trace { "Signatures received are valid. Trade complete! :-)" } return fullySigned } @Suspendable -open fun receiveAndValidateTradeRequest(): SellerTradeInfo { +private fun receiveAndValidateTradeRequest(): SellerTradeInfo { // Wait for a trade request to come in on our pre-provided session ID. - val maybeTradeRequest = receive<SellerTradeInfo>(TRADE_TOPIC, sessionID) - + val maybeTradeRequest = receive<SellerTradeInfo>(sessionID) maybeTradeRequest.validate { // What is the seller trying to sell us? - val asset = it.assetForSale.state + val asset = it.assetForSale.state.data val assetTypeName = asset.javaClass.name logger.trace { "Got trade request for a $assetTypeName: ${it.assetForSale}" } @@ -589,15 +583,16 @@ open fun receiveAndValidateTradeRequest(): SellerTradeInfo { } @Suspendable -open fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller { +private fun swapSignaturesWithSeller(stx: SignedTransaction, theirSessionID: Long): SignaturesFromSeller { + progressTracker.currentStep = SWAPPING_SIGNATURES logger.trace { "Sending partially signed transaction to seller" } // 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, SignaturesFromSeller::class.java).validate { it } + return sendAndReceive<SignaturesFromSeller>(otherSide, theirSessionID, sessionID, stx).validate { it } } -open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedTransaction { +private fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: TransactionBuilder): SignedTransaction { // Now sign the transaction with whatever keys we need to move the cash. for (k in cashSigningPubKeys) { val priv = serviceHub.keyManagementService.toPrivate(k) @@ -607,40 +602,39 @@ open fun signWithOurKeys(cashSigningPubKeys: List<PublicKey>, ptx: Transac return ptx.toSignedTransaction(checkSufficientSignatures = false) } -open fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> { - val ptx = TransactionBuilder() +private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> { + val ptx = TransactionType.General.Builder(notary) // Add input and output states for the movement of cash, by using the Cash contract to generate the states. val wallet = serviceHub.walletService.currentWallet val cashStates = wallet.statesOfType<Cash.State>() val cashSigningPubKeys = Cash().generateSpend(ptx, tradeRequest.price, tradeRequest.sellerOwnerKey, cashStates) // Add inputs/outputs/a command for the movement of the asset. - ptx.addInputState(tradeRequest.assetForSale.ref) + ptx.addInputState(tradeRequest.assetForSale) // Just pick some new public key for now. This won't be linked with our identity in any way, which is what // we want for privacy reasons: the key is here ONLY to manage and control ownership, it is not intended to // reveal who the owner actually is. The key management service is expected to derive a unique key from some // initial seed in order to provide privacy protection. val freshKey = serviceHub.keyManagementService.freshKey() - val (command, state) = tradeRequest.assetForSale.state.withNewOwner(freshKey.public) - ptx.addOutputState(state) - ptx.addCommand(command, tradeRequest.assetForSale.state.owner) + val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public) + ptx.addOutputState(state, tradeRequest.assetForSale.state.notary) + ptx.addCommand(command, tradeRequest.assetForSale.state.data.owner) // 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(Instant.now(), timestampingAuthority, 30.seconds) + val currentTime = serviceHub.clock.instant() + ptx.setTime(currentTime, 30.seconds) return Pair(ptx, cashSigningPubKeys) }
    -

    This code is longer but still fairly straightforward. Here are some things to pay attention to:

    +

    This code is longer but no more complicated. Here are some things to pay attention to:

    1. We do some sanity checking on the received message to ensure we’re being offered what we expected to be offered.
    2. -
    3. We create a cash spend in the normal way, by using Cash().generateSpend. See the contracts tutorial if this isn’t -clear.
    4. +
    5. We create a cash spend in the normal way, by using Cash().generateSpend. See the contracts tutorial if this +part isn’t clear.
    6. We access the service hub when we need it to access things that are transient and may change or be recreated -whilst a protocol is suspended, things like the wallet or the timestamping service. Remember that a protocol may -be suspended when it waits to receive a message across node or computer restarts, so objects representing a service -or data which may frequently change should be accessed ‘just in time’.
    7. +whilst a protocol is suspended, things like the wallet or the network map.
    8. Finally, we send the unfinished, invalid transaction to the seller so they can sign it. They are expected to send back to us a SignaturesFromSeller, which once we verify it, should be the final outcome of the trade.
    @@ -648,12 +642,8 @@ back to us a SignaturesFromSell the fact that it takes minimal resources and can survive node restarts.

    Warning

    -

    When accessing things via the serviceHub field, avoid the temptation to stuff a reference into a local variable. -If you do this then next time your protocol waits to receive an object, the system will try and serialise all your -local variables and end up trying to serialise, e.g. the timestamping service, which doesn’t make any conceptual -sense. The serviceHub field is defined by the ProtocolStateMachine superclass and is marked transient so -this problem doesn’t occur. It’s also restored for you when a protocol state machine is restored after a node -restart.

    +

    In the current version of the platform, exceptions thrown during protocol execution are not propagated +back to the sender. A thorough error handling and exceptions framework will be in a future version of the platform.

    @@ -787,6 +777,39 @@ directly to the a.services.reco valid).

    And that’s it: you can explore the documentation for the MockNode API here.

    +
    +

    Versioning

    +

    Fibers involve persisting object-serialised stack frames to disk. Although we may do some R&D into in-place upgrades +in future, for now the upgrade process for protocols is simple: you duplicate the code and rename it so it has a +new set of class names. Old versions of the protocol can then drain out of the system whilst new versions are +initiated. When enough time has passed that no old versions are still waiting for anything to happen, the previous +copy of the code can be deleted.

    +

    Whilst kind of ugly, this is a very simple approach that should suffice for now.

    +
    +

    Warning

    +

    Protocols are not meant to live for months or years, and by implication they are not meant to implement entire deal +lifecycles. For instance, implementing the entire life cycle of an interest rate swap as a single protocol - whilst +technically possible - would not be a good idea. The platform provides a job scheduler tool that can invoke +protocols for this reason (see “Event scheduling”)

    +
    +
    +
    +

    Future features

    +

    The protocol framework is a key part of the platform and will be extended in major ways in future. Here are some of +the features we have planned:

    +
      +
    • Automatic session ID management
    • +
    • Identity based addressing
    • +
    • Exposing progress trackers to local (inside the firewall) clients using message queues and/or WebSockets
    • +
    • Exception propagation and management, with a “protocol hospital” tool to manually provide solutions to unavoidable +problems (e.g. the other side doesn’t know the trade)
    • +
    • Being able to interact with internal apps and tools via HTTP and similar
    • +
    • Being able to interact with people, either via some sort of external ticketing system, or email, or a custom UI. +For example to implement human transaction authorisations.
    • +
    • A standard library of protocols that can be easily sub-classed by local developers in order to integrate internal +reporting logic, or anything else that might be required as part of a communications lifecycle.
    • +
    +
    diff --git a/docs/build/html/release-notes.html b/docs/build/html/release-notes.html index 35c581b1b2..7894558134 100644 --- a/docs/build/html/release-notes.html +++ b/docs/build/html/release-notes.html @@ -93,12 +93,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -243,7 +244,7 @@ in the upcoming releases.

    New documentation:

    diff --git a/docs/build/html/release-process.html b/docs/build/html/release-process.html index c668266653..e7ee747deb 100644 --- a/docs/build/html/release-process.html +++ b/docs/build/html/release-process.html @@ -93,12 +93,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -195,10 +196,10 @@ create one, bug them to do so a day or two before the release.
  • Regenerate the docsite if necessary and commit.
  • Create a branch with a name like release-M0 where 0 is replaced by the number of the milestone.
  • Adjust the version in the root build.gradle file to take out the -SNAPSHOT and commit it on the branch.
  • +
  • Remove the “is master” warning from the docsite index page on this branch only.
  • Tag the branch with a tag like release-M0.0
  • Push the branch and the tag to git.
  • -
  • Write up a short announcement containing the summary of new features, changes, and API breaks. Send it to the -r3dlg-awg mailing list.
  • +
  • Write up a short announcement containing the summary of new features, changes, and API breaks. Send it to the r3dlg-awg mailing list.
  • 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 diff --git a/docs/build/html/running-the-demos.html b/docs/build/html/running-the-demos.html index f19d4f7383..b92778c8a7 100644 --- a/docs/build/html/running-the-demos.html +++ b/docs/build/html/running-the-demos.html @@ -32,7 +32,7 @@ - + @@ -93,6 +93,7 @@

  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos

    Contracts

    Tutorials

    @@ -181,11 +182,6 @@ rates oracle, all driven via the HTTP API.
  • The demos create node data directories in the root of the project. If something goes wrong with them, blow away the directories and try again.

    -
    -

    Note

    -

    Corda is developed on MacOS and works best on UNIX systems. Both demos are easily run on Windows but -you won’t get the nice coloured output.

    -

    Trader demo

    Open two terminals, and in the first run:

    @@ -265,7 +261,7 @@ can see the other terminals whilst you run this command!:

    1. Install Node: https://nodejs.org/en/download/ and ensure the npm executable is on your classpath
    2. Open a terminal
    3. -
    4. Run npm install -g bower or sudo npm install -g bower if on a *nix system.
    5. +
    6. Run npm install -g bower or sudo npm install -g bower if on a Unix system.
    7. In the terminal navigate to <corda>/src/main/resources/com/r3corda/demos/irswebdemo
    8. Run bower install
    @@ -315,7 +311,7 @@ blotter to view it.

    Next - Previous + Previous
    diff --git a/docs/build/html/search.html b/docs/build/html/search.html index b6e9fbff03..2e9712cc50 100644 --- a/docs/build/html/search.html +++ b/docs/build/html/search.html @@ -91,12 +91,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    diff --git a/docs/build/html/searchindex.js b/docs/build/html/searchindex.js index 1a3462b6a7..5cf5a8e6d7 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","contract-catalogue","contract-irs","data-model","event-scheduling","getting-set-up","index","inthebox","messaging","node-administration","oracles","protocol-state-machines","release-notes","release-process","running-the-demos","transaction-data-types","tutorial-contract","tutorial-contract-clauses","tutorial-test-dsl","visualiser","where-to-start"],objects:{},objnames:{},objtypes:{},terms:{"0_xx":7,"1mb":13,"8u45":7,"_before_":13,"_do_":13,"_foo":1,"_is_":13,"_mbeans_":11,"abstract":[5,13,14,18],"boolean":[5,18],"break":[12,15,18],"byte":[1,5,9,13,20],"case":[1,2,5,10,12,13,14,17,18,19],"catch":[1,7,13],"class":[],"default":[1,3,7,9,13,14,16,18,19],"enum":14,"export":[11,13,22],"final":[2,4,5,7,10,13,18,19,20],"float":[3,4,6,9],"function":[],"import":[1,5,6,7,10,13,14,15,18,19,20,22],"instanceof":[18,19],"int":[1,2,18],"long":[1,3,5,6,10,13,18],"new":[1,2,4,5,7,8,9,10,11,13,14,15,17,18,19,20,22],"null":[6,12,18],"public":[1,5,9,10,11,12,13,17,18,19,20],"return":[1,2,4,6,10,11,12,13,14,18,19,20,22],"short":[6,10,15,18],"static":[5,12,13,18,20,22],"super":1,"switch":[9,13,14,18],"throw":[1,2,12,13,18,19],"transient":13,"true":[5,10,12,18,21],"try":[1,5,13,16,18,21,22],"var":[13,18],"void":[18,19,20],"while":[17,18],abil:[5,10],abl:[2,5,10,12,14,16],abort:2,about:[],abov:[1,4,5,10,13,18,19,20],absolut:5,abstractnod:12,accept:[1,2,3,5,10,13,18],acceptablepric:13,access:[1,5,7,10,11,12,13,18],accid:13,accident:1,accompani:1,accord:22,accordingli:[10,19],account:[5,17],accrual:4,accur:12,accuraci:5,achiev:[2,5,10],ack:14,acknowledg:13,across:[3,5,13,14],act:[2,5,10,12,13],action:[6,18,22],activ:[4,6,16],actor:[1,5,13],actual:[4,7,10,12,13,18,20],adapt:[1,12,13],add:[1,10,11,13,17,18,19,20],addarg:18,addcommand:13,addinputst:[13,18],addit:[1,2,5,17,18],addition:[12,13,15],addmessagehandl:[10,14],addoutputst:[13,18],address:[2,5,10,13,16,18],adjust:[1,4,15,22],admin:7,administr:[],advanc:[3,4,8],advantag:5,adventur:22,advertis:12,advertisedservic:2,advic:15,affect:[7,12],affection:18,affinityexecutor:1,afraid:1,after:[2,3,4,5,6,7,9,12,13,18,19,21],again:[4,5,10,12,13,16,18],against:[4,5,6,13,18,19],agent:11,aggreg:[5,18,19],agre:[4,6,13],agreement:[4,5,17],ahead:13,aim:[1,5],albeit:14,albertsen:14,algorithm:[5,9,14,18,21],alic:[18,21],aliceaddr:10,alicegetsback:[18,21],alicenod:10,aliv:13,all:[0,1,2,3,4,5,7,10,11,12,13,14,15,16,18,19,22],allevi:2,allow:[1,2,3,4,5,6,9,12,13,17,18,20,22],allpossiblerecipi:10,almost:[13,18],along:[2,9,10,12,13,18],alreadi:[1,6,12,13,14,18,19,20],alright:13,also:[1,2,3,4,5,6,7,10,11,13,16,17,18,19,20,22],alt:18,alter:[13,18],altern:[0,1,11,17],although:[4,5,9,10,18,19,22],alwai:[1,5,6,11,13,18,19],amounnt:13,amount:[],amqp:[9,14],analysi:5,andresen:5,ani:[1,2,3,4,5,6,10,11,12,13,15,16,17,18,19,22],annot:[1,13,18],announc:15,anonym:5,anoth:[1,2,7,11,12,13,18,20],answer:[1,12],anticip:1,anybodi:5,anyon:[2,18],anyth:[2,5,10,12,13,18,19],anywher:[10,12,18],apach:[9,10],apart:2,api:[],app:[11,14,15,22],appear:18,append:11,appendix:8,appli:[1,3,4,5,18,19],applic:[5,12,22],applyfix:4,appoint:2,approach:[],appropri:[1,10,19],approv:[5,6,13],arbitrari:[1,5,12,13,18],arbitrarili:9,architectur:[8,12],area:[10,17],aren:[13,18,22],arg:[14,18,21],arguabl:12,argument:[1,5,10,13,18],aris:5,around:[5,10,12,13,14,15,17,18,21],arrai:[5,9,13],arrang:13,arraylist:19,arriv:[12,13],arrow:[4,7],artemi:9,articl:[2,5,6,10,12,13,22],artifact:18,ask:[1,13,18],aspect:[6,13,22],assembl:5,assemblesharedtx:13,assertequ:13,asset:[],assetforsal:13,assetmismatchexcept:13,assettosel:13,assettypenam:13,assign:[12,13],assist:[6,13,18,21],associ:[2,5,6,10,17,18],assum:[5,12,13,18],assumpt:13,atom:[5,12,13,16,18],attach:[],attack:2,attempt:[5,7,8,10,13],attent:13,attest:[2,12],attribut:1,audit:[5,13],authent:2,authenticatedobject:[17,18,19],author:[1,2,5,10,13,15,22],authoris:13,auto:[1,18],autom:[5,6,18,22],automat:[0,6,10,13,14,18,22],avail:[0,4,6,10,11,12,15,18],avoid:[1,5,13],awai:[5,13,16],awar:[1,13],awg:15,awkward:[1,13],axi:4,back:[1,5,12,13,17,18],backend:10,background:[1,5,10],backport:15,backtick:18,backward:[13,15],bad:[1,13,18,20],balanc:[2,3,5,18,20],banana:17,bananast:17,banco:14,band:13,bandwidth:1,bank:[4,5,14,17,22],bankrupt:18,bankruptci:[5,12],barreca:14,barrel:14,base:[],basi:[4,6,11],basic:[],bat:16,bbva:14,bear:[13,18],beauti:21,becaus:[1,5,7,10,11,12,13,17,18,19,20],becom:[1,4,5,6,13,15],been:[2,4,5,7,12,13,14,15,18],befor:[2,4,5,6,9,12,13,14,15,17,18],beforehand:16,begin:[1,5,16,18,22],behav:18,behaviour:[2,11,19,20],behind:[13,18],believ:14,below:[1,4,5,6,13,22],beneficiari:3,benefit:[2,13,18],best:[1,16,22],bet:12,better:[1,8,9,14,18,21],between:[1,4,5,6,10,12,13,14,15,16,17,18],beyond:[5,18],big:[1,5,13,14,18],bigdecim:12,bilater:[3,4,9,14],bill:18,bin:16,binari:[5,12],bind:[2,5,12],bip:5,bit:[13,18,20,21,22],bitbucket:7,bitcoinj:13,blah:1,blank:[1,18],block:[1,2,5,8,10,12,13,14,18],blockchain:[5,9,13],bloom:1,bloomfilt:1,blotter:16,blow:16,blue:[4,21],bob:18,bobaddr:10,bobnod:10,bodi:1,boil:5,bond:18,bookkeep:[9,18],boost:9,borrow:21,both:[2,3,4,5,9,10,12,13,16,18],bottom:13,bounc:13,bound:[12,13],bower:16,box:[9,22],branch:15,breach:5,bread:22,breadth:13,breviti:19,brief:14,briefli:[10,21],bring:5,broadcast:[5,10],broke:1,broken:18,browser:16,bug:[1,14,15],bugfix:15,bui:[13,22],builder:[13,14,18],built:[13,18],bulk:[5,19],bullet:1,bunch:[16,18],bundl:5,busi:[5,6,9,10,12,13,17,18,22],businesscalendar:17,butter:22,button:16,buyer:[],buyersessionid:13,bytearrai:10,bytecod:[5,13,18],cach:10,calcul:[4,6,13,17,18],calendar:[4,12,17],calibr:5,call:[1,2,4,5,9,10,11,13,14,15,18,19,20],callback:[1,10,13],caller:[2,18],came:13,camel:1,can:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,16,17,18,19,20,21,22],cannot:[2,3,5,7,12,14,18],capabl:18,capit:1,capitan:0,captur:6,cardon:14,care:[1,5,10,12,13,20],carefulli:9,cash:[],cashkt:18,cashsigningpubkei:13,cashstat:13,caus:[1,18],center:18,certain:[1,9,14,18],certainti:2,cev:7,chain:[],chaincash:20,chaincashdoublespend:20,chaincashdoublespendfailswith:20,challeng:5,chanc:[1,13],chang:[],changenotari:2,channel:13,charact:1,charg:12,check:[],checkabl:12,checkdepend:13,checksufficientsignatur:[13,17],chf:17,child:13,children:13,childrenfor:13,choic:[1,2,5],choos:[2,7,18],chosen:[2,5],chronolog:6,chunk:[18,22],circl:21,claim:[5,9,18],clash:1,classpath:16,claus:[],clauseverifi:[18,19],clean:[13,14],cleanup:14,clear:[13,17],clearer:[10,13],clearli:1,click:[7,16,21],client:[2,11,12],clock:[6,12,16],clone:[1,7],close:[3,12],closer:2,closur:[1,20],cloud:11,cluster:2,cmd:[18,19],coars:5,code:[],codebas:[1,18],cognit:5,coin:5,collabor:14,colleagu:1,collect:[1,11,14,19],collector:[1,11,13,19],collis:1,colour:16,column:11,com:[0,7,14,16,19,20],combin:[5,8,18,19],come:[5,9,13,14,15],command:[],commanddata:[12,19],commerci:[],commercial_pap:[18,19],commercialpap:[3,9,18,19,21],commercialpaperlegaci:18,commercialpapertest:[18,21],commit:[2,13,15],commod:17,common:[4,5,13,14,17,18,20],commonleg:4,commonli:18,commun:[7,14],compani:12,companion:[13,18,19],compar:[5,10],compat:15,compel:2,complementari:6,complet:[5,6,10,13,14,16,17,18,19,20],complex:[1,3,5,13,17,18],complic:[13,18],compon:[6,10,14],compos:[13,14,17,18,19],compris:4,comput:[4,12,13],concept:[2,5,6,12,13,14,18],conceptu:13,concern:[5,13,18],conclus:[5,12],concurrenthashmap:1,condit:[2,12,13,20],config:11,configur:[7,11,13,16],confirm:[2,7,10],conflict:[2,5,8],confus:13,connect:[11,18],consid:[1,4,5,12,14,15,18],consist:[4,5,13,14,19],constant:[1,18],constantli:12,constraint:12,construct:[1,2,10,12,13,14,17,18,20,22],constructor:[6,12,18],consult:12,consum:[2,5,6,14],consumingtx:2,consumpt:[6,12],contact:[7,13],contain:[2,4,5,10,11,12,13,15,16,17,18,19,20,22],content:[1,2,5,6,7,10,11,12,13,18],context:[1,5,11,12,17],continu:[],contract:[],contractreject:20,contractst:[2,6,14,17,18,21],contractstateref:18,contrast:[5,12,13],contribut:17,control:[1,2,5,7,11,13,14,16,18,22],conveni:[1,5,18],convent:[4,13,19],convers:17,convert:[3,4,13,17,18],convinc:13,copi:[1,5,10,13,18,20,22],copyonwritearraylist:1,copyright:1,corda:[],cordapp:14,core:[3,10,14,17,18,19,20],corner:7,correct:[2,3,5,14,15,18,20],correctli:[5,12,14,18],correspond:18,correspondingli:1,cost:[12,18],could:[1,2,3,5,12,13,17,18],count:4,countabl:14,counter:[1,13],counterparti:[3,4],countri:[12,17],coupl:[12,13],cours:[11,12,18,22],cover:[2,3,5,12,13,17,18,22],cp_program_id:18,creat:[],createdummyir:4,createmessag:10,createsomenod:13,creation:[4,5,8,18],creator:12,credit:14,crisp:18,criteria:3,critic:[5,15],crop:5,curl:11,currenc:[3,4,9,14,17,18],current:[1,2,4,5,6,9,10,12,13,14,15,17,18,20,21],currentwallet:13,curv:4,custodi:13,custom:[2,11,14,16,17],customis:22,cut:[],cycl:1,dai:[4,6,11,12,15,17,18,21],daniel:14,danks:14,dashboard:11,data:[],databas:[5,9,13],dataset:4,date:[],dateoffset:14,daterollconvent:17,david:14,deadlin:17,deal:[1,12,16,17],dealstat:17,debt:3,debug:13,decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9:11,decd:11,decentralis:12,decid:[7,12,18],decis:[2,5],declar:[1,10,18,20],dedic:1,defin:[1,2,5,9,10,11,12,13,14,17,18,19,20,21,22],definit:[2,13,17,18,19],delai:[4,12],delet:[1,5,13,14,18],deliber:[5,20],deliv:[3,10,13,17],deliveri:[9,10,13,16,18],demand:[5,17],demo:[],demonstr:[14,16,22],denial:2,denomin:9,dens:1,depend:[1,2,5,6,7,12,13,14,18,19],dependencytxid:13,deposit:[9,18,20],depth:18,deregist:10,deriv:[4,13,18],describ:[1,2,5,6,8,13,17,18],descript:1,deserv:15,design:[1,2,5,8,9,12,18,19,22],desir:[13,17,18],desktop:11,despit:[13,18],destin:10,destroi:[3,5,18],destroypaperatredempt:[18,21],destructur:18,detail:[],detect:1,determin:[3,4,6],develop:[1,5,9,10,13,14,15,16,18],devic:5,devis:5,diagram:[4,21],diamond:21,didn:[1,13,15,18],differ:[1,3,4,5,6,12,13,14,17,18,19,20],difficult:[10,13],digest:2,digit:[5,12,13,14,18],digitalsignatur:[2,12,13],direct:1,directli:[1,11,13,17,18],directori:[0,16,18,22],directthreadexecutor:1,dirti:18,disabl:17,disadvantag:5,discov:5,discuss:[5,10,17,18],disk:[13,14,17],disobei:12,disprov:8,disput:[2,4,18],disrupt:10,distinct:1,distinguish:18,distribut:[2,5,8,9,12,13],distrust:[2,13],divid:2,dlg:13,doc:[0,1,14,18],docker:11,docsit:[0,15],doe:[1,2,3,4,5,6,9,10,11,12,13,18,20,22],doesn:[1,2,5,7,10,11,12,13,16,18,20],dokka:0,dollar:[18,20,21],domain:[14,17,18,21],don:[1,5,7,9,10,13,15,18,19,20],done:[0,5,13,14,18],dot:4,doubl:[5,9,16,18],doubt:[1,9],down:[1,5,12,18,19],download:[],downsid:[1,5],drag:21,drive:[5,22],driven:16,driver:[14,22],drm:12,dsl:[14,18,20,21],due:[1,4,5,6,9,12,13,18,19],dummi:[3,13,18,20],dummy1:13,dummy2:13,dummy_cash_issu:20,dummy_notary_kei:13,dummy_pubkey_1:[18,20],dummy_pubkey_2:20,dummycontract:13,duplic:18,durat:[6,12,18],dure:[1,4,6,14],dynam:[14,18,22],each:[1,2,4,5,6,9,10,12,13,14,15,18,19,20,22],earli:[1,18,21,22],earliest:[4,6],eas:10,easi:[1,5,9,12,14,18],easier:[1,13,18],easiest:18,easili:[1,12,13,16],econom:4,ed25519:14,edit:7,editor:7,effect:[4,5,13,20],either:[1,2,3,4,5,12,13,18,19,20,22],elbonia:17,element:[1,5,19],elimin:9,els:[2,5,13,18,19],emb:[6,18],embed:[5,11,12],emit:18,empti:[14,18,19,20],emptyledg:20,enabl:18,encapsul:[1,17],enclos:1,encod:12,encount:9,encrypt:9,end:[1,4,9,12,13,15,19,22],endpoint:11,enforc:[1,5,18],enforceverifyorfail:20,engin:18,english:[1,18],enorm:13,enough:[1,7,10,13,18,22],ensur:[1,2,5,7,10,13,15,16,17,18],enter:[18,20,22],entir:[2,4,5,10,12,18],entireti:4,entiti:[2,5,12,18],entri:[4,5,13,18],enumer:4,environ:[1,12,13],envisag:18,equal:[2,13,18,19,20],equival:[1,4,17,18],especi:[17,21],essenti:[11,12,17,18,19],establish:[6,16],etc:[1,3,4,12,13,14,15,17,18],euribor:[11,12],evalu:[4,12],even:[5,9,10,12,13,14,18,20],event:[],eventu:15,ever:[1,5],everi:[2,5,12,13,14,15,18,22],everybodi:[5,12],everyon:[2,12],everyth:[2,10,18,22],evid:12,evolut:5,evolv:[18,22],exact:[12,18],exactli:[5,10,18],examin:[1,5,12,13,18],exampl:[],excel:12,except:[1,13,18,19],excess:1,exchang:[4,13,17,18],exclus:3,execut:[5,6,12,16,17,18,19],executor:[1,10],exercis:18,exhaust:14,exist:[1,2,3,4,5,6,8,14,18,20,22],exit:[3,13,18],expect:[1,3,6,10,13,15,18,19,20],expectedtypenam:13,expectfailureoftx:18,expens:1,experi:[5,15,22],experiment:[1,6,13,14],explain:[1,6,10,13,14],explan:1,explicit:[1,5,12,13],explicitli:[1,5,18,20],explor:[1,5,7,8,9,11,13,18,22],exploratori:10,expos:[1,6,10,11,12,13,17],exposur:[3,4],express:[4,5,9,12,13,14,18,20],extend:[1,2,9,17,18,19],extens:[1,14,17,18],extent:5,extern:[13,22],extract:[5,11,12,13,17,18],extractcommand:19,extractgroup:19,extrem:[5,12,18],face:[9,18,21],facevalu:18,fact:[1,2,4,5,12,13,18,20],factor:[4,5],factori:6,fail:[10,18,20],failswith:20,failur:[13,18,20],fairli:[1,13],fake:[16,18,22],fals:[1,10,12,13,17,18],familiar:[5,18],famou:14,far:[13,16,18],fashion:1,fast:[5,10,13,16],fault:13,featur:[1,13,14,15,18,21],feed:12,feedback:14,feel:[18,22],fetch:[10,11,12],few:[1,9,10,11,12,13,15,16,18],fiber:13,field:[1,4,12,13,14,18,19,21],file:[0,1,5,10,11,13,14,15,16,17,18,22],fill:[1,13,16,18],filter:[1,19],filterisinst:18,finalis:[4,13],financ:[13,14,22],financi:[5,6,8,13,14],find:[0,5,11,13],fine:[5,20],finish:[10,13],firm:18,first:[1,2,4,6,7,10,11,12,13,14,16,17,18,19,22],firstli:18,fit:[1,5],fix:[],fixabledealst:17,fixedleg:4,fixedlegpaymentschedul:4,fixedratepaymentev:4,fixingroledecid:6,fixingsessioninitiationhandl:6,fixof:12,flag:[11,22],flexibl:[2,5],flight:5,floatingleg:[4,6],floatinglegpaymentschedul:4,floatingratepaymentev:4,flow:[1,4,18,19],flux:22,fly:13,fold:1,folder:0,follow:[0,1,2,5,6,7,8,10,11,12,13,16,17,18,19,20,21],font:1,foo:[1,10],foobrokenexcept:1,fooutil:18,forc:[5,11,14,20],fordai:[6,12],forev:15,forget:[13,18],form:[2,5,6,13,16,18,19],formal:[10,18],format:[0,1,5,11],forth:13,forward:[10,12,13,15,16],found:[7,11,12,13,15,19,22],four:[9,18],frame:[1,13],framework:[],free:[5,12,13],freeform:18,freeli:12,frequenc:4,frequent:13,fresh:[12,18,20],freshkei:13,freshli:[17,18],from:[0,1,2,3,4,5,7,9,10,11,12,13,14,15,16,17,18,19,20,21,22],fromcountri:17,front:18,frustrat:5,fulfil:3,full:[1,2,3,10,13,18,19],fulli:[1,5,10,13,14,17,18],fullysign:13,fun:[2,6,12,13,18,19,20],fund:5,fundament:[2,5,8,18],fungibl:[3,9,17,18,19],fungibleasset:[],funni:13,further:[4,5,9,17],futur:[2,3,5,12,13,17,18,21,22],gain:9,game:13,garbag:[1,11,13],gather:18,gavin:5,gbp:17,gcd:5,gear:15,gener:[],generateiniti:13,generateirsandfixsom:4,generateissu:18,generatemov:18,generateredeem:18,generatespend:[13,18],genuin:1,get:[],getamount:20,getbefor:18,getbloomfilters:1,getclass:18,getclaus:19,getcommand:[18,19],getdummy_cash_issu:20,getdummy_pubkey_1:20,getdummy_pubkey_2:20,getfacevalu:18,getfix:4,getifmatch:19,getifnotmatch:19,getinput:[14,18],getinst:14,getissu:18,getkei:18,getlegalcontractrefer:[18,19],getmaturityd:18,getmega_corp:20,getmega_corp_pubkei:20,getnotarysignatur:2,getoutput:[14,18],getoutst:14,getown:[18,19],getprogramref:18,getprotocoltrack:13,getrequiredcommand:19,getsign:[18,19],getter:18,gettim:18,gettimestampbi:18,gettransact:13,getvalu:[18,19],git:[7,15],github:0,giusepp:14,give:[2,5,13,18],given:[2,5,10,12,13,18],givenpric:13,global:[1,5,12,14],glue:13,gnu:0,goal:[1,5,8,9,13,15],goe:16,gone:[13,14,18],good:[1,7,13,18,20,21,22],got:[11,13],gover:18,grade:17,gradl:[7,15],gradlew:[7,16],grammar:1,granular:5,graph:[5,9,11,13,18,21],graphit:11,great:14,greater:1,greatest:5,green:7,groom:5,group:[],groupclaus:19,groupclauseverifi:19,groupstat:[18,19],guarante:15,guava:1,gui:13,hack:[5,14],had:[2,13,14,18],hand:[6,13,18],handa:14,handi:13,handl:[1,2,5,10,13,14,18,19],handler:[6,10,13],happen:[1,2,5,6,12,13,15,18,20],happi:16,hard:[1,5,13,15],harder:[5,18],hase:4,hash:[2,5,9,11,12,13,17,18],hashcod:18,hasn:7,hassl:13,hat:15,have:[1,2,3,4,5,6,7,9,10,12,13,14,15,16,18,19,20,22],haven:18,heap:13,hearn:5,heart:18,heavi:15,heavili:5,hedg:[3,4],heirarchi:1,held:18,hell:13,hello:13,help:[1,5,6,10,13],helper:[4,10,17,18],henc:[2,4,5],her:[18,21],here:[1,5,9,10,11,12,13,14,17,18,20,21,22],hierarch:13,hierarchi:13,high:[5,12,13],higher:[1,2,7,18],highlight:[14,18],histori:[2,13],hit:[5,7],hoc:14,hold:[5,10],holder:[1,5,18],holidai:[4,12,17],home:[7,16],hood:[13,20],hopefulli:22,hotspot:1,how:[],howev:[2,3,4,5,10,12,13,17,18,19,20],html:[0,1],http:[0,7,11,12,16,18,19,22],hub:13,human:[5,12,13],hundr:13,hurt:13,hypothesi:8,idea:[1,5,7,9,13,18,22],ideal:[13,18],ident:[2,5,12,13,17,18,19,20],identifi:[4,5,9,10,11,12,13,17],identityless:5,identityservic:13,ifmatch:[14,19],ifnotmatch:[14,19],ignor:[18,19],illeg:12,illegalargumentexcept:[1,12,13,18,19,20],illegalstateexcept:1,illustr:1,imagin:[1,13,18],immedi:[5,18],immut:[1,4,5,12,18],imper:1,implement:[],impli:13,implic:[2,5],implicitli:4,impos:[12,13,18],imposs:[5,12],improv:[5,14,15,18,19,21],inbackground:10,includ:[],incompat:20,incorpor:12,increas:[1,10],indent:1,independ:[2,12,19],index:[4,5,6,7,18],indexsourc:6,indic:[1,4,6,10,13,14,18],individu:[1,10,16,18,20],industri:[8,9,11],infer:[18,20],infix:18,influenc:11,info:13,inform:[1,2,5,13,17,18],infrastructur:[5,9,11,13],inher:5,inherit:[1,10,18],init:12,initi:[2,10,13,14,18,22],initialis:[2,13],inmemorymessagingtest:10,inner:19,inoutgroup:[18,19],input:[2,3,5,12,13,14,17,18,19,20,21],inputcash:20,inputindex:2,insert:[1,10,11,12,13],insid:[5,10,13,16,18],instal:[0,6,7,16],installdist:16,instanc:[],instant:[1,6,12,13,17,18],instanti:[5,6,13,14],instat:20,instead:[1,5,6,9,13,14,16,18,22],instig:2,institut:[5,9],institutionrefer:18,instruct:[11,18],instrument:[3,4,6],insuffici:5,insufficientbalanceexcept:18,integ:[14,18],integr:[1,12,13,14,21],intellig:1,intend:[1,3,5,11,12,13,17,20],intent:[12,18,21],intention:1,inter:[9,14],interact:[1,5,12,13,14],interchang:17,interest:[],interestrateswap:9,interfac:[],intern:[1,9,10,17,18],internalis:1,interop:[9,18],interpret:[1,5,18],intersect:18,interv:17,intesa:14,introduc:[1,2,6,12,14,17,18],introductori:8,intuit:1,invalid:[2,12,13,18],invari:18,investig:13,invoc:10,invok:[1,5,6,10,11,13,14,18],involv:[2,3,5,10,12,13,17,18,22],ipsa:12,irrelev:6,irsdemo:16,irsexport:4,irstest:4,irsutil:4,irswebdemo:16,isbefor:18,isempti:18,isinst:13,isn:[1,13,18,22],issu:[2,3,5,9,10,12,13,14,15,17,18,19,20,21,22],issuanc:[3,13,17,18,19,21],issuedbi:20,issuer:[3,5,13,18,20],item:18,iter:[13,15,18],itself:[2,4,5,6,10,11,12,13,18,20],jar:[0,5,11],jarinputstream:5,java:[1,5,6,9,10,11,13,14,18,19,20,22],javaclass:13,javacommercialpap:[18,19],javadoc:1,javatesthelp:20,jdk1:7,jdk:[7,13,14,18],jetbrain:[7,9],jmx2graphit:11,jmx:11,jmxtran:11,job:22,johann:14,join:[10,18],joint:18,jolokia:11,json:[11,22],judgement:1,jump:16,junit:18,just:[1,5,7,10,11,13,14,17,18,20,22],justifi:8,jvm:[5,9,11,13,22],kafka:10,kdoc:1,keep:[5,13,18,21],kei:[1,3,5,9,10,12,13,17,18,20],kept:13,key_mismatch_at_issu:18,keymanagementservic:13,keypair:[13,18],keyword:[1,18,20],kick:13,kind:[5,9,10,12,13,18,22],know:[2,5,6,9,12,13,16,20],knowledg:12,known:[],kotin:18,kotlin:[],kryo:[10,13],label:[13,18,20,21],labori:18,lack:[],lambda:20,land:4,lang:20,languag:[1,5,7,8,9,14,17,18,21,22],larg:[5,12,13,14,17,18,22],larger:[1,5],last:[15,20],lateinit:13,latenc:[2,12],later:[1,5,9,10,12,13,14,17,18,19],latest:[1,7,14],latter:[1,18],launch:6,layer:[5,10,13],layout:21,lead:[1,5,18],leak:[2,5,13],learn:[5,8,13,16,18,22],least:[12,18],leav:[1,13],ledger:[2,3,4,5,8,11,12,13,14,18,20,21],ledgertransact:17,left:[10,13,16,19,20],leg:[4,6,9],legal:[2,5,12,17,18],legalcontractrefer:[18,19],legallyidentifi:[2,12,13],legallyidentifiablenod:13,less:[13,18,21],let:[1,5,6,11,12,13,14,16,17,18,19,20],letter:1,level:[1,2,4,7,10,12,13,17,18,19,20],lib:0,liber:1,libor:[4,11,12],librari:[1,11,12,13,17,18],licens:1,life:22,lifecycl:[],lifecyl:3,lifetim:4,lightweight:13,like:[1,2,4,5,6,7,10,11,12,13,15,17,18,19,22],likewis:18,limit:[3,5,8,18],line:[],linearst:17,liner:1,link:[1,5,12,13,17,18],linkabl:5,linux:[11,14],list:[0,5,10,12,13,14,15,16,17,18,19],listen:1,listenablefutur:13,listof:[13,19],liter:5,littl:[1,18,20],live:4,livelock:5,load:[2,5,14,16,17,18,22],loan:[3,4,12],local:[0,5,7,11,12,13,20],locald:12,localhost:[11,16],locat:[17,18],lock:[1,3,18],log4j:14,log:[13,14,16],logger:13,logic:[2,5,6,9,10,13,14,18,19,22],longer:[1,4,12,13,14],look:[1,4,10,11,12,13,15,18,19,20,22],loop:[1,4,18],loquitur:12,loss:12,lot:[1,4,5,16,22],low:[2,13],lower:[1,12],lurch:13,mac:11,machin:[],maco:16,made:[1,4,5,8,13,14,15,19],mai:[1,5,9,10,11,12,13,14,15,18,19,20,22],mail:[15,16],main:[6,13,16,18,21,22],maintain:[2,5],maintan:12,mainten:10,major:15,make:[0,1,2,4,5,10,12,13,14,15,16,18],makenod:10,maker:9,maketransact:13,malici:13,manag:[],mani:[1,5,6,9,10,12,13,14,17,18],manipul:17,manner:13,manual:[6,10],map:[],mappabl:18,mark:[1,3,13,18],markdown:1,marker:[13,18],market:8,master:15,match:[5,10,12,13,18,19],matchbehaviour:19,matter:18,matur:[3,4,11,12,18],maturityd:18,maven:7,maximis:5,maximum:5,maybestx:13,maybetraderequest:13,mbean:11,mean:[1,5,6,10,12,13,17],meaning:[2,3],measur:[4,18],mechan:[14,18],meet:18,mega_corp:[13,18,20],mega_corp_kei:[13,18],mega_corp_pubkei:[20,21],megacorp:[13,18,21],member:[4,14],memori:[],menlo:1,mention:[6,13],menu:7,mere:[4,18],merg:[5,9,14,17,18],mess:13,messag:[],messagehandlerregistr:10,messagerecipi:10,messagerecipientgroup:10,messagingservic:[10,13],method:[],metric:11,micro:19,middl:[1,10,13],might:[1,4,5,7,13,18],mike:5,mileston:[],mind:[1,12,13,18],mine:5,mini:[],mini_corp_pubkei:13,minim:[5,13],minimis:[2,3,5,10],minimum:[4,5],minor:15,minu:18,minut:[9,12],misc:10,mismatch:20,miss:[1,13,18,20,22],missingsig:13,mission:11,mix:[1,13,18],mock:[10,13],mocknetwork:13,mocknod:13,mockservic:17,mode:10,model:[],modest:5,modif:[17,18],modifi:[2,3,4,7,13,17,18,19],modul:[1,10,13,14,18],moment:[10,13,14],monei:[12,18],monetari:18,monitor:[],month:[4,13,15],more:[1,2,3,4,5,9,10,11,12,13,14,16,17,18],moreexecutor:1,mortensen:14,most:[1,4,5,10,11,12,13,18],mostli:18,move:[3,13,14,15,18,19,20,21],movement:[13,18],much:[1,5,9,13,14,18,22],multi:[1,9,13,18],multilater:[3,14],multipli:4,must:[1,2,3,5,6,10,11,12,13,16,17,18,19,22],mustafa:14,mutabl:[1,5,17,18],mutat:5,mutual:[2,3,13],myfil:11,mykei:17,mykeypair:13,nail:1,namedbyhash:17,namespac:13,narrow:1,nativ:13,natixi:14,natur:18,naval:[5,12],navig:16,navistar:12,neat:20,necessari:[1,2,15,16],nee:14,need:[0,1,2,4,5,6,8,10,11,13,15,16,17,18,19,20,22],negoti:[5,17],neither:[13,18],nest:13,net:[3,4,13,14,18,21],nettabl:9,network:[],neutral:9,never:[1,5,12,18,19],newli:[6,13],newnotari:2,newown:18,newsecurerandom:14,next:[1,4,6,7,13,14,18],nextfixingof:6,nextscheduledact:6,nice:16,nio:1,nix:16,noddi:11,node:[],nodea:16,nodeb:16,nodeinterestr:12,nodej:16,nodeservic:12,non:[],none:[6,13,19],nonemptyset:14,nordea:14,normal:[3,4,13,17,18,19],not_matured_at_redempt:18,notabl:1,notaris:[2,17],notarychang:14,notarychangeprotocol:2,notaryexcept:2,notarynod:13,notaryprotocol:2,notaryservic:14,notarytous:17,notat:13,note:[],noth:[1,5,6,14,18],notic:[1,18],notif:10,notifi:10,notion:[4,5,18],notnul:[18,19],now:[1,5,7,10,12,13,14,16,17,18,20,21,22],npm:16,nugget:18,nullpublickei:18,number:[1,3,4,5,10,12,13,15,16,17,18],numer:5,obj:18,object:[1,3,4,5,6,9,10,11,12,13,14,17,18,19,21,22],oblig:[],obligor:3,observ:[4,5,6,12,13],observatori:[5,12],obsolet:6,obtain:[],obviou:[1,2,5,12],obvious:[4,18],occasion:[],occur:[2,6,12,13,18],occurr:12,odd:[13,18],off:[10,13,18,21],offer:13,offlin:10,offset:4,often:[1,3,4,5,12,13,18],oftenor:12,oil:[14,20],old:2,omit:6,onc:[0,1,2,4,6,9,10,12,13,15,17,18,22],onli:[1,2,4,5,9,10,11,12,13,14,18,19,21,22],onto:[1,13,18,21],opaqu:[9,10],opaquebyt:18,open:[2,5,7,12,13,16,21],openjdk:7,oper:[4,6,10,11,12,13,18],optim:1,option:[0,1,4,6,10,12,13,18,19,22],oracl:[],orchestr:[8,9,14,22],ordain:4,order:[0,1,2,3,4,5,9,10,13,17,18,19,21],ordinari:[5,13,18],org:[0,7,16,18,19],orient:[],origin:[17,18],originalst:2,otc:9,other:[1,2,3,4,5,6,9,10,12,13,16,17,18,20],othersid:13,otherwis:[1,6,13,18,19],our:[1,2,5,6,13,14,15,18,20],ourselv:[13,18,22],oursignatur:13,out:[1,2,3,5,6,7,9,11,12,13,15,18,19],outag:10,outcom:13,outer:19,outermost:19,outlin:[5,8,13],outpoint:5,output:[2,3,5,12,13,14,16,17,18,19,20,21],outref:13,outsid:[5,10,12,13,18,22],outstand:3,outstat:18,over:[1,2,4,5,10,11,12,13,17,18],overal:[2,6,10,20],overdu:6,overflow:1,overload:13,overnight:17,overrid:[6,13,18,19],overwhelm:5,own:[1,2,3,10,11,12,13,14,15,18,20,21,22],ownablest:[13,17],owned_bi:18,owner:[13,17,18,19,20],ownership:[13,18],owningkei:[13,18],ozturk:14,p2p:[13,14],pack:18,packag:14,packet:5,page:[7,12,16,18],pai:[3,12,13,18,21],paid:[3,4,5],pair:[5,13,18],paper:[],paper_1:[18,21],parallel:[5,10,13],parallelis:5,paramet:[1,6,13,16,18,19],parameteris:5,parent:13,pars:[12,22],part:[1,2,3,5,6,12,13,14,17,18,19,22],parti:[],partial:[2,13,18,20],partialtx:13,particip:[2,5,14,18,22],particular:[1,2,5,11,13,14],partyandrefer:1,partynod:13,partyrefer:[1,18],pascal:1,pass:[2,10,13,18,19,21],past:[1,12,16,18,22],patch:1,path:[1,6,11,14,18],pattern:[1,5,18],paye:5,payer:[4,5],payment:[3,4,5,6,12,13,16,18,21],pdf:12,peer:[9,10,12,13],penni:18,peopl:[1,5,9,18],per:[1,5,6,22],perform:[1,2,4,5,6,12,13,16,18],perhap:[1,5,6,18],period:4,perman:18,persist:[9,10,13,14],perspect:[5,13,18],phrase:12,physic:[2,12,14],pick:[10,13,14,15,18,22],piec:[1,2,5,10,13,18,20],ping:10,pip:0,pki:[5,14],place:[0,1,4,5,6,9,10,12,13,14,15,17,18,22],plai:13,plan:[10,16],platform:[],pleas:[1,5,7,14,16,18],pluggabl:14,plugin:[7,11],point:[1,2,3,5,6,11,12,13,15,18],pointer:[2,13,17],pointless:1,pong:10,pool:[1,5,13],poor:5,pop:[7,10],popular:9,popup:7,port:[14,15,16],posess:13,posit:[1,2,5,13],possess:2,possibl:[5,10,12,13,18],post:19,potenti:[1,2,9,13,18],pound:18,power:[5,8],practic:[5,18],pre:[0,4,5,13,18,20,22],preced:18,precis:[5,9,12],precondit:1,prefer:[1,5],prefix:[1,13],preliminari:10,prepar:[5,18],present:[2,3,4,8,12,17,18,19],preserv:[2,5],press:18,pretend:[11,17],pretti:[5,13,18],prevent:18,previou:[5,14,17,20],previous:[4,6,12,14],price:[5,12,13],primari:[9,12],primarili:3,primit:[18,20],print:16,priv:13,privaci:[1,2,5,13,14,18],privat:[1,5,13,18,19,22],privatefoo:1,probabl:[7,12,18,22],problem:[2,5,12,13],proce:13,procedur:13,process:[],processor:5,produc:[0,6,18,20,21],product:[1,6,8,9,15,17,18],profit:[18,21],profound:5,program:[1,5,10,11,13,14,16,17,18,22],programref:18,progress:[],progresstrack:13,project:[7,14,16],prolif:14,promis:14,proof:[5,8],propag:[8,11,18,19],properli:13,propos:[8,13],prose:[12,17],protect:13,protocol:[],protocollog:[6,13],protocollogicref:6,protocollogicreffactori:6,protocolstatemachin:13,protocoltrack:13,prototyp:[1,5,8,9,12,18],prove:[2,5,8,18],provid:[0,1,2,3,4,5,10,11,12,13,14,17,18,22],provision:17,pseudo:12,ptx:13,pubkei:20,publicfoo:1,publickei:[],publicli:[],pull:7,pump:10,punish:12,purchas:[13,16],pure:[3,5,12],purpos:[3,9,13,18],push:15,put:[1,13,15,18,22],python:0,qualiti:8,quantiti:[5,9,18],quasar:13,queri:[4,6,12],question:[1,2,6,7,12],queu:10,queue:[1,10,13],quick:12,quickli:[5,10,18],quit:[1,12,13,18],r3corda:[14,16,19,20],r3dlg:15,r3prototyp:[0,7,16],r3repositori:7,rais:[2,19],random63bitvalu:13,random:[5,6,13,14],rang:12,rapid:[1,9,15],rate:[],ratefixprotocol:12,rather:[1,5,13,14,18],raw:[11,13],reach:[2,4,5,6,12],reachabl:13,read:[1,5,8,9,11,12,13,18,22],readabl:[9,13],reader:18,readi:[15,18],readili:17,readm:1,real:[1,10,12,14,17,18,22],realis:13,realism:10,realist:17,realiti:4,realli:[1,2,5,13,18],reason:[1,4,5,13,17,18],reassign:18,recal:4,receiv:[3,4,5,10,12,13,15,18,21],receiveandcheckproposedtransact:13,receiveandvalidatetraderequest:13,recent:14,recipi:[3,5,10,18],recognis:[5,12,18],recommend:[1,10,22],record:[2,6,10,13],recordtransact:[6,13],recov:10,recreat:13,red:[4,7],redeem:[3,9,18,19,21],redempt:[18,21],redemptiontim:[18,21],redesign:14,reduc:1,redund:1,ref:[13,18,20],refactor:14,refer:[1,2,3,4,5,6,9,12,13,14,17,18,20],referenc:2,refin:9,reflect:[18,19],refus:7,regard:2,regardless:13,regener:[4,15],regist:[1,10,11,13,22],registr:10,regular:[11,13,18],reissuanc:[5,18],reject:18,rel:[5,10,19],relabelablestep:13,relat:[4,18],relationship:18,releas:[],relev:[5,14,17,19],reli:5,reliabl:10,relianc:5,relic:11,religi:1,remain:[6,18,21],remeb:7,rememb:[1,6,7,13,18],remind:13,remot:7,remov:[10,13,18],renam:14,render:[1,13,21],repeat:[1,4,10,13],replac:[2,4,7,11,14,15,17,18],replic:5,repoint:2,report:[10,19],repositori:[],repres:[1,3,4,5,10,12,13,17,18],represent:4,request:[2,5,10,12,13,14],requestingparti:2,requiredcommand:[14,19],requiresinglecommand:[18,19],requirethat:[18,19],research:14,resel:12,reserv:13,reset:4,reshap:5,resolut:[2,5,8,13],resolv:[1,13,17],resolvefromtwohash:13,resolvetransactionsprotocol:13,resolvetransactionsprotocoltest:13,resourc:[13,16],respect:[1,5,13,16,18],respend:5,respons:[2,5,6,10,12,13],rest:[2,5,9,10,11,13,14,22],restart:[7,13],restor:13,restrict:1,restructur:19,restructuredtext:0,result:[1,2,4,5,12,13,18,19],resultfutur:13,resum:[13,14],resurrect:13,retain:10,retri:[9,10,13],retriev:[2,4],retrieveoutput:20,reus:[5,13,20],reusabl:[12,14,18,19],reveal:[2,5,13,18],revers:13,revert:3,review:[1,14,15],revis:4,rewrit:13,right:[1,7,10,11,13,15,22],rigid:5,rigidli:1,risk:13,robert:14,robust:14,role:[6,16,22],roll:[4,13,16],rollov:[17,18],root:[15,16,18,21],rotat:14,roughli:[12,15],rout:13,router:10,rui:14,ruin:20,rule:[1,12,13,14,18],run:[],runbuy:13,runnetwork:[10,13],runsel:13,runtim:[1,13],safe:[1,5,13,18],safeti:1,sai:[1,2,5,18],sale:[16,18],same:[1,2,3,4,5,6,9,10,12,13,16,18,19,20,21],sandbox:[5,6,9,18],saniti:13,santiago:14,satisfi:18,save:[1,14,18],scala:[9,18],scalabl:[1,5],scale:4,scenario:[5,22],scene:[13,18],schedulablest:6,scheduledact:6,scope:[5,18,19],scotiabank:14,scrape:11,scratch:[17,22],screen:[1,7],script:[0,5,18],scroll:16,scrub:13,seamless:9,search:[7,13,18],second:[4,13,16,17,18],secondari:13,secp256r1:14,section:[5,15,18],secur:[5,6,10,13],securehash:[2,18,19],securerandom:14,see:[0,1,2,3,4,6,9,10,12,13,16,17,18,19,22],seed:13,seek:5,seem:5,seen:[1,4,12,13,18,21],select:[2,7,14,18,19],self:14,sell:[13,18,22],seller:[],sellerownerkei:13,sellersig:13,sellertradeinfo:13,semi:[5,12],send:[1,5,10,11,12,13,15,18,20],sendandrec:13,sender:5,sendsignatur:13,sens:[4,12,13,18],sensit:6,sent:[6,10,13,18],separ:[2,5,11,12,13,16,17,18],sequenc:[5,10],sequenti:[10,13],seri:13,serial:[9,10,18],serialis:[1,5,9,10,13,18],serializablewithkryo:18,serializeablewithkryo:18,seriou:[5,15],serious:22,server:[11,12,22],servicehub:[6,13],session:[6,10,13],sessionid:[6,13],set:[],setof:[13,19],setter:18,settim:[13,17],settl:[3,10,12,13,17],settlement:[3,13],setup:[6,13],setupa:16,setupb:16,sever:[5,13,18,20,22],sha256:[18,19],sha256sum:11,sha:[5,11],shape:5,share:[4,5,12,13,14,18,19,22],shasum:11,she:18,shortcut:9,shorthand:[18,20],shot:10,should:[1,2,3,5,6,7,9,10,13,14,16,17,18,19,20,22],shoulder:1,shouldn:[13,18],show:[5,7,9,16,18,21],shown:[13,18],shutdown:13,side:[12,13],sig:18,sign:[2,4,5,9,10,12,13,14,17,18,19,20],signatureexcept:13,signaturesfromsel:13,signedtransact:[13,17,18],signer:[12,18,19],signific:[5,14],significantli:4,signoff:12,signwith:[13,17,18],signwithecdsa:13,signwithourkei:13,silver:1,similar:[1,5,10,12,14,18,19],simpl:[1,3,4,5,9,10,11,13,18,19,21],simplecash:20,simplecashdoesntcompil:20,simplecashfailswith:20,simplecashsuccess:20,simplecashtweaksuccess:20,simplecashtweaksuccesstopleveltransact:20,simplenotaryservic:2,simpler:[5,9],simplest:[5,13,18,22],simpli:[1,2,5,10,13,17,18,20],simplif:14,simplifi:[1,3,5,10,17,18,22],simultan:[5,10,13,18],singl:[],singleclaus:19,singlemessagerecipi:[10,13],singleton:[13,18,19],singletonlist:19,sit:10,site:[1,15],situat:[1,5],size:[1,4,5,13,18,19],skeleton:13,skip:[13,17],slight:18,slightli:18,slip:15,slow:[1,5],slowest:5,small:[5,6,12,13,16,18,21],smaller:14,smart:[],smm:13,smooth:18,snake:20,snapshot:[5,14,15],snide:0,snippet:[2,13,18],softwar:[13,15,22],sofu:14,sold:[13,18,21],solv:[5,12,13],solvenc:12,some:[1,2,3,5,6,9,10,11,12,13,14,16,17,18,19,20,21,22],somed:18,someon:[2,5,10,18],someprofit:[18,21],someth:[1,4,5,7,16,17,18,19,22],sometim:[5,10,11,12,13,18],somewhat:[5,13,14],somewher:[18,21],sophist:5,sort:[12,13],sound:[1,13,18,21],sourc:[4,6,7,12,13],sparingli:1,special:[2,5,20],specialis:[13,19],specif:[2,5,6,10,11,12,13,14,17,18,19,21],specifi:[0,1,2,3,5,9,10,12,13,14,18,19,20,22],speed:[5,13],spend:[5,9,13,18],spent:[5,20],sphinx:0,sphinx_rtd_them:0,spirit:14,split:[5,9,14,17,18],spread:[2,10,13],spreadsheet:12,squar:21,src:[16,18,21,22],ssl:[9,14],stabilis:15,stabl:15,stack:13,stage:[1,13,18,22],stai:[5,18],stake:5,standalon:12,standard:[1,8,11,13,17,18,19],standardis:[5,17,18],start:[],startprotocol:13,state:[],stateandref:[2,13,17,18],statehistori:2,stateless:5,statemachinemanag:13,statement:[1,5,12,13,18],stateref:[2,5,6,17],statesoftyp:13,statist:11,status:5,step:[],still:[2,5,6,13,14,18,22],stock:[5,12],stop:[1,10,13],stopnod:13,storag:[5,13],store:[2,13,14,17,18],stori:[1,14],straightforward:[13,18],stream:[13,19],stress:1,strictli:[4,5],string:[10,12,13,18],strong:9,structur:[1,5,7,9,12,13,18],studi:18,stuff:[1,13],stx1:13,stx2:13,stx:[13,17],sub:[1,13],subclass:[13,17],subclaus:19,subgroup:5,submiss:12,submit:[1,2,10,13,16],subprotocol:[2,13],subscrib:10,subsequ:20,subset:3,subtask:13,subtl:[1,5],successor:[2,6,9],succinct:1,sudo:[0,16],suffer:5,suffic:12,suffici:[5,8,10,12,15,17],suffix:18,suggest:[10,18],suggestinterestrateannouncementtimewindow:6,suit:14,suitabl:[6,10,15],sukrit:14,sum:[18,20],sumcashbi:[13,18],sumcashornul:18,summari:[],summaris:5,sun:1,superclass:[13,14,17],superior:1,supersed:5,supertyp:18,suppli:[3,16],support:[],suppos:[13,18],suppress:[1,14],suppresswarn:1,sure:[2,14,15,16,18,22],surfac:13,surround:[1,18],surviv:13,suspend:[],swap:[],swapsignatureswithsel:13,symbol:7,synchronis:[1,5,12],syntax:[9,18],system:[2,5,9,11,12,13,14,16,18],tab:[1,7],tackl:[14,19],tag:[1,15],tailor:8,take:[1,4,6,9,13,15,17,18,19,20,21],talk:13,tamper:13,target:[0,1,5,9,11,13],targetrecipi:10,task:[5,6,13],team:7,teardown:13,technic:[],techniqu:[1,5,12,18],tell:[0,10,13],templat:17,tempor:12,temporari:5,temporarili:[13,15],tempt:18,temptat:13,ten:18,tenor:[4,11,12,17],term:[3,5,6,17,18,19],termin:[4,11,13,16],terminolog:5,test:[],test_tx_tim:18,testutil:18,testwithinmemorynetwork:10,text:[1,7,11,20],than:[1,2,5,8,11,13,14,18,21],thank:14,thedao:14,thei:[1,3,4,5,6,9,10,11,12,13,15,16,17,18,19],theirsessionid:13,them:[1,4,5,6,7,9,10,11,13,14,15,16,17,18,20,22],themselv:[10,12,13,17,18],theori:[],therefor:[5,7,9,13,15,18],thi:[0,1,2,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22],thing:[1,5,6,9,12,13,14,16,17,18,22],think:[1,5,7,13,18],third:[5,16,18],thisstateref:6,those:[5,6,10,11,12,13,16,17,18],though:[10,11,13,18],thought:[5,9],thousand:20,threadsaf:1,three:[16,17,18],threshold:18,through:[4,5,6,11,13,14,18,19,20,22],throughput:[2,5],throwifsignaturesaremiss:13,thrown:[18,19],thu:[1,5,6,11,12,17,18],tidi:13,tighten:18,tightli:13,time:[1,2,3,4,5,6,9,11,12,13,14,16,17,18,21],timelin:18,timestamp:[],timestampauthoritysig:13,timestampcommand:[12,18],timestampercli:18,timestamperservic:12,timestampingauthor:13,timestampingprotocol:13,titl:7,todo:[1,13,18],togeth:[3,5,13,14,18,19],token:[17,19],told:1,toledgertransact:[13,17],toler:[2,6,12],tolist:19,too:[1,13,18,21],took:13,tool:[9,11],toolbar:7,top:[1,5,7,13,16,18,19],topic:[10,13,22],topicsess:14,toplevel:20,topriv:13,toset:13,tosignedtransact:[13,17,18],tostr:[1,13,18],total:[5,18],toward:[14,15],towiretransact:17,trace:13,track:[],tracker:13,trade1:16,trade:[],trade_top:13,tradeoff:[],trader:[],traderdemo:22,traderequest:13,tradit:[5,18],traffic:[5,13],transact:[],transactionbuild:[13,14,17,18],transactionforcontract:19,transactionforverif:18,transactiongroup:18,transactiongroupdsl:21,transactiongroupfor:21,transactiongroupfortest:18,transactionst:[2,14,17],transactiontyp:14,transactionverificationexcept:20,transfer:[18,20],transit:[8,18,22],treat:18,tree:13,tri:[5,18],tricki:[5,13],trigger:[3,6,12,16,19],trim:19,trivial:[1,5],trust:[3,5,13],truth:13,tsa:[5,13],tsasig:13,tupl:1,ture:5,turn:[5,13,17,18,19,20,22],tutori:[3,8,9,12,13,14,18,19,20,22],tweak:20,twice:[9,20],two:[],twopartydealprotocol:6,twopartytradeprotocol:13,txb:17,txbit:13,txhash:[5,13,18],txt:11,type:[],typenam:13,typetobui:13,typic:[5,6,10,11,13,17,18,22],unacceptablepriceexcept:13,under:[0,13,15,18,20,22],underli:[3,4,5,13,17],underscor:[1,18],understand:[5,10,11,18,21,22],unexecut:18,unexpect:13,unfinish:13,unfortun:[13,18],unguess:13,unicredit:14,unifi:[14,22],uniform:6,unindex:7,uniqu:[2,5,12,13,14],unit:[2,5,7,8,9,10,21,22],unix:[11,16],unknow:12,unless:[1,12,13,15,18,22],unlik:[3,7,18],unmatch:19,unnatur:5,unnecessari:18,unpack:[13,18],unprocess:19,unqiu:6,unread:13,unrecognis:18,unrel:18,unreleas:[],unschedul:6,unserialis:13,unset:4,unspent:5,unstart:13,unsupportedoperationexcept:18,until:[2,4,5,6,10,13,15,19,20,22],untrustworthydata:13,unus:10,unusu:18,unverifiedtransact:20,upcom:[6,14],updat:[5,7,10,13,14,15,18],upgrad:[7,8,14],upload:[],upon:[4,13,18],upward:15,url:[7,16],usabl:[9,14,15],usag:[1,12,13,18],usd:17,useless:18,user:[0,1,5,7,9,10,12,13,14],usr:0,usual:[1,5,15],utc:6,util:[10,14,18],vagu:1,val:[1,2,6,10,12,13,17,18,19,20,21],validatedtransact:13,validatingnotaryservic:2,valu:[1,3,4,5,9,12,14,18,19,20,21],valuabl:12,valuat:4,vanilla:[3,4,9],vari:[],variabl:[1,4,5,13,18],variant:18,variou:[1,5,9,11,13,18],vehicl:5,vendor:[9,11],verbos:18,veri:[1,3,5,9,12,20,21,22],verif:[3,5,9,19,20],verifi:[],verifyclaus:19,verifytransact:13,versa:[3,4,13,17],version:[4,7,10,13,14,15,17,18],versu:13,vertic:1,via:[0,1,4,5,6,11,12,13,16,18,22],vice:[3,4,13,17],view:[1,4,16],virtual:[5,8],visibl:[2,5],vision:8,visualis:[],vital:13,wai:[1,5,6,9,11,12,13,14,18,19,20,22],wait:[6,7,10,13,16],wake:14,wallet:[5,6,13,14,18],walletservic:13,want:[1,5,7,10,11,12,13,14,18,20,22],weak:12,wear:15,web:[11,12],websit:18,weekend:4,well:[0,1,4,5,6,9,11,12,13,17,18,19],went:1,were:[1,5,12,13,18],what:[],whatev:[1,13,17],when:[1,2,3,4,5,6,10,11,12,13,14,17,18,20],whenev:1,where:[],wherea:4,wherev:11,whether:[2,3,10,12,13,19],which:[0,1,2,3,4,5,6,8,9,10,11,12,13,14,15,16,17,18,19,20,22],whilst:[5,12,13,16,18],whitelist:[3,6],whitepap:8,who:[1,5,9,10,13,14,18],whole:[2,18,20],whom:[3,5,10],whose:[11,17],why:[1,5,9,18],wide:[1,10,18],widescreen:1,widespread:1,width:1,wiki:[5,18,19],wikipedia:[18,19],window:[5,7,13,16,21],wire:22,wirecommand:18,wiretransact:[2,12,13,17],wish:[5,10,12,13,14,18,22],within:[0,1,2,5,11,16,20],withitem:17,withkei:13,withnewown:13,without:[],withoutown:[18,19],won:[10,12,13,16,18,20],word:[1,2],work:[1,2,4,5,6,7,8,9,10,11,12,13,14,16,17,18],worker:1,world:[5,12,13,18,20],worn:18,worri:[1,9,13],worst:5,worth:[1,18],worthless:12,would:[1,3,4,5,9,10,11,12,13,17,18,22],wouldn:[12,18],wrap:[1,11,13,14,17,18,19,22],wrapper:[1,2,13],write:[],written:[0,4,5,9,14,18],wrong:[1,13,16,20],wrote:5,wtx:[2,12,13],www:[0,7],year:4,yet:[1,4,5,9,13,14,17,18],yield:[5,13],you:[0,1,5,6,7,9,10,11,12,13,14,16,17,18,19,20,21,22],your:[],your_usernam:7,yourself:5,zero:[5,18],zip:[5,11],zone:6,zoneddatetim:6},titles:["Building the documentation","Code style guide","Consensus model","Platform contracts","Interest Rate Swaps","Data model","Event scheduling","Getting set up","Welcome to the Corda repository!","What’s included?","Networking and messaging","Node administration","Writing oracle services","Protocol state machines","Release notes","Release process","Running the demos","Data types","Writing a contract","Writing a contract using clauses","Writing a contract test","Using the visualiser","Where to start"],titleterms:{"class":[18,19],"function":18,about:7,administr:11,adopt:5,amount:17,api:18,approach:12,assert:[1,12],asset:18,attach:11,base:18,basic:12,bitcoin:5,build:0,buyer:13,cash:[3,17],chain:20,chang:2,check:18,claus:[18,19],code:1,command:18,comment:1,commerci:[3,18,19],comparison:5,compil:1,complain:7,con:5,consensu:2,continu:12,contract:[3,9,18,19,20],corda:8,creat:4,cut:15,data:[5,12,17],date:17,demo:[16,22],detail:4,document:0,download:11,error:1,ethereum:5,event:6,exampl:6,fix:11,framework:12,fungibleasset:17,gener:[1,18],get:7,group:[18,19],guid:1,how:[6,18],implement:[6,10,12,13],includ:9,instanc:4,intellij:7,interest:[3,4,11],interfac:10,introduct:[6,12,13],known:12,kotlin:9,lack:7,length:1,lifecycl:[4,17],line:1,machin:13,manag:13,map:10,memori:10,messag:10,method:13,mileston:14,model:[2,5],monitor:11,multipl:2,name:1,network:10,node:11,non:18,notari:2,note:14,oblig:3,obtain:2,occasion:12,oracl:12,orient:18,overview:5,paper:[3,18,19],parti:[13,17],platform:3,pro:5,process:15,progress:13,properti:1,protocol:13,publickei:17,publicli:12,rate:[3,4,11],rational:5,releas:[14,15],repositori:8,requir:[0,18],run:[2,16],schedul:6,sdk:7,seller:13,servic:[2,10,12],set:7,signatur:2,singl:20,smart:18,space:1,start:[18,22],state:[13,17,18],step:15,style:[1,5],summari:19,support:17,suspend:13,swap:[3,4],technic:4,test:[13,18,20],theori:13,thread:1,timestamp:2,track:13,trade:13,tradeoff:5,trader:[16,22],transact:[17,20],two:[12,13],type:17,unit:13,unreleas:[],upload:11,utxo:5,valid:2,vari:12,verifi:18,visualis:21,warn:1,web:16,welcom:8,what:9,where:22,without:7,write:[12,18,19,20],your:[11,18]}}) \ No newline at end of file +Search.setIndex({envversion:47,filenames:["building-the-docs","codestyle","consensus","contract-catalogue","contract-irs","creating-a-cordapp","data-model","event-scheduling","getting-set-up","index","inthebox","messaging","node-administration","oracles","protocol-state-machines","release-notes","release-process","running-the-demos","transaction-data-types","tutorial-contract","tutorial-contract-clauses","tutorial-test-dsl","visualiser","where-to-start"],objects:{},objnames:{},objtypes:{},terms:{"0_xx":8,"1mb":14,"8u45":8,"_before_":14,"_do_":14,"_foo":1,"_is_":[],"_mbeans_":[],"abstract":[6,14,15,19],"boolean":[6,19],"break":[13,14,16],"byte":[1,6,14,21],"case":[1,2,5,6,13,14,15,18,19,20],"catch":[1,8,14],"class":[],"default":[1,3,8,14,15,17,19,20],"enum":15,"export":[12,14,23],"final":[2,4,6,8,14,19,21],"float":[3,4,7],"function":[],"import":[1,6,7,8,14,15,16,18,19,20,21,23],"instanceof":19,"int":[1,2,19],"long":[1,3,6,7,14,19],"new":[1,2,4,6,8,9,10,11,12,14,15,16,18,19,20,21,23],"null":[7,19],"public":[1,6,10,11,12,14,18,19,20,21],"return":[1,2,4,7,12,14,15,19,20,21,23],"short":[7,16],"static":[5,6,13,14,19,21,23],"super":[1,20],"switch":[14,15,19],"throw":[1,2,14,19,20],"transient":14,"true":[2,6,13,19,22],"try":[1,6,14,17,22,23],"var":14,"void":[19,20,21],"while":[18,19],abil:6,abl:[2,6,13,14,15,17],abort:[2,13],about:[],abov:[1,4,6,14,19,20,21],absolut:[2,6],abstractnod:[],accept:[1,2,3,6,14,19],acceptablepric:14,access:[1,8,11,12,13,14,19],accid:14,accident:1,accompani:[1,19],accord:23,accordingli:20,account:[6,18],accrual:4,accur:2,accuraci:6,achiev:[2,6],ack:15,acknowledg:14,across:[3,6,15],act:[2,6,13,14],action:[7,19,23],activ:[4,7,17,19],actor:[1,6,14],actual:[2,4,8,13,14,19,20,21],adapt:[1,13,14],add:[1,6,11,12,14,19,20,21],addarg:[],addcommand:[14,19],addinputst:[14,19],addit:[1,2,6,18,19],addition:[6,14,16],addmessagehandl:15,addoutputst:[14,19],address:[2,6,11,14,17,19],adjust:[1,4,16,19,23],admin:8,administr:[],advanc:[3,4,9],advantag:6,adventur:23,advertis:19,advertisedservic:[],advic:16,affect:[8,13],affection:[],affinityexecutor:1,afraid:1,after:[2,3,4,5,7,8,10,13,14,19,22],again:[4,6,13,14,17,19],against:[4,6,7,14,19,20],agent:12,aggreg:[6,19,20],agre:[4,7,14],agreement:[4,6,18],ahead:[14,19],aim:[1,6],albeit:15,albertsen:15,algorithm:[6,10,15,18,19,22],alic:[19,22],aliceaddr:[],alicegetsback:22,alicenod:[],aliv:14,all:[0,1,2,3,4,6,8,12,13,14,15,16,17,18,19,20,23],allclaus:20,allcomposit:20,allevi:2,allow:[1,2,3,4,5,6,7,11,13,14,18,19,21,23],allpossiblerecipi:[],almost:19,along:[2,13,14,19],alreadi:[1,7,13,14,15,19,20,21],alright:14,also:[1,2,3,4,5,6,7,8,11,12,14,17,18,19,20,21,23],alt:[],alter:14,altern:[0,1,11,12,18,19],although:[4,6,14,19,20,23],alwai:[1,6,7,12,14,18,19],amounnt:[],amount:[],amqp:[11,15],analysi:6,andresen:6,ani:[1,2,3,4,6,7,12,13,14,16,17,18,19,23],annot:[1,14],announc:16,anonym:6,anoth:[1,2,6,8,12,13,14,19,21],answer:[1,13],anticip:1,anybodi:6,anyclaus:20,anycomposit:20,anyon:[2,19],anyth:[2,6,14,18,19,20],anywher:[13,19],apach:11,apart:2,api:[],app:23,appear:19,append:12,appendix:9,appli:[1,3,4,6,19,20],applic:[5,6,11,13,23],applyfix:4,appoint:2,approach:[],appropri:[1,11,20],approv:[6,7,14],approxim:2,arbitrari:[1,6,13,14,18],arbitrarili:6,architectur:[9,13],area:[],aren:[7,10,19,23],arg:[15,22],arguabl:[],argument:[1,6,14,19],aris:6,around:[2,6,14,15,16,18,19,22],arrai:[6,14],arrang:14,arraylist:[],arriv:[13,14],arrow:[4,8],art:18,artemi:11,articl:[2,6,7,13,14,19,23],artifact:[],ask:[1,13,14,19],aspect:[14,23],assembl:[6,19],assemblesharedtx:14,assertequ:14,asset:[],assetforsal:14,assetmismatchexcept:14,assettosel:14,assettypenam:14,assign:[6,13,14],assist:[7,14,22],associ:[2,6,7,11,18,19],assum:[2,6,14,19],assumpt:14,atom:[2,6,14,17,19],attach:[],attack:2,attempt:[6,8,9],attent:14,attest:2,attribut:1,audit:6,authent:2,authenticatedobject:[18,19,20],author:[1,2,16,23],authoris:14,auto:[1,19],autom:[6,7,19,23],automat:[0,2,5,7,11,14,15,19,23],avail:[0,2,4,7,12,14,16,19],avoid:[1,6,14],awai:[6,14,17],awar:[1,7,14,19],awg:16,awkward:[1,14],axi:4,back:[1,6,13,14,18,19],backend:[],background:[1,6],backoff:11,backport:16,backtick:[],backward:[14,16],bad:[1,14,19,21],balanc:[2,3,6,19,21],banana:18,bananast:18,banco:15,band:14,bandwidth:1,bank:[4,6,15,18,19,23],bankrupt:19,bankruptci:[2,6,13],barreca:15,barrel:15,base:[],basi:[4,7,12],basic:[],bat:17,bbva:15,bear:14,beauti:22,becaus:[1,2,6,7,8,12,13,14,18,19,20,21],becom:[1,4,6,7,14,16,18],been:[2,4,6,8,13,14,15,16,18,19,20],befor:[2,4,6,7,10,14,15,16,18,19,20],beforehand:17,begin:[1,6,17,19,23],behav:19,behaviour:[2,3,12,20,21],behind:[11,14,19],believ:15,below:[1,4,6,7,14,18,23],beneficiari:3,benefit:[2,14],best:[1,23],bet:13,better:[1,9,10,15,19,22],between:[1,2,4,6,7,11,13,14,15,16,17,18,19],beyond:6,big:[1,6,14,15,19],bigdecim:[13,18],bilater:[3,4,15],bill:19,bin:17,binari:[6,13],bind:[2,6,13],bip:6,bit:[14,18,19,21,22,23],bitbucket:8,bitcoinj:14,blah:1,blank:[1,19],block:[1,2,6,9,13,14,15],blockchain:[6,10,14,19],bloom:1,bloomfilt:1,blotter:17,blow:17,blue:[4,22],bob:19,bobaddr:[],bobnod:[],bodi:1,boil:6,boilerpl:19,bond:19,bookkeep:19,boost:10,bore:19,borrow:22,both:[2,3,4,6,10,13,14,18,19],bottom:[],bounc:14,bound:[2,14,19],bower:17,box:23,branch:[9,16],breach:6,bread:23,breadth:[],breviti:20,brief:15,briefli:[11,22],bring:6,broadcast:[2,6,19],broadcasttransactionprotocol:2,broke:1,broken:19,broker:11,browser:17,bug:[1,15,16],bugfix:16,bui:[14,23],builder:[14,15],built:[2,5,14,19],bulk:[6,20],bullet:1,bunch:17,bundl:6,busi:[6,7,10,13,14,18,19,23],businesscalendar:18,butter:23,button:17,buyer:[],buyersessionid:14,bytearrai:[],bytecod:[6,14,19],cach:11,calcul:[2,4,7,14,18,19],calendar:[4,13,18],calibr:[],call:[1,2,4,6,10,12,14,15,16,18,19,20,21],callback:[1,14],caller:[2,19],came:14,camel:1,can:[0,1,2,3,4,5,6,7,8,10,11,12,13,14,15,17,18,19,20,21,22,23],cannot:[2,3,6,8,13,15,18,19],capabl:[],capit:1,capitan:0,captur:7,cardon:15,care:[1,2,6,14,21],carefulli:10,cash:[],cashkt:19,cashsigningpubkei:14,cashstat:14,caus:[1,19],cent:18,center:19,central:[18,19],certain:[1,15,19],certainti:2,cev:8,chain:[],chaincash:21,chaincashdoublespend:21,chaincashdoublespendfailswith:21,challeng:6,chanc:[1,14],chang:[],changenotari:2,channel:14,charact:1,charg:13,check:[],checkabl:13,checkdepend:[],checknotnul:19,checkstat:19,checksufficientsignatur:[2,14,18],chf:[],child:14,children:14,childrenfor:14,choic:[1,2,6,19],choos:[2,8,19],chosen:[2,6,14],chronolog:7,chunk:[19,20,23],circl:22,claim:[6,19],clash:1,classic:19,classpath:[6,17],claus:[],clauseverifi:20,clean:[14,15],cleanup:15,clear:[14,18],clearer:14,clearli:1,click:[8,17,22],client:[2,12,14],clock:[2,6,7,14,17],clone:[1,8],close:[2,3],closer:2,closur:[1,21],cloud:12,cluster:2,cmd:[19,20],coars:6,code:[],codebas:1,cognit:6,coin:6,collabor:15,colleagu:1,collect:[1,12,15,19,20],collector:[1,12,14],collis:1,colour:[],column:12,com:[0,8,15,17,19,21],combin:[6,9,18,19],come:[6,14,15,16,19],command:[],commanddata:[13,19,20],commerci:[],commercial_pap:[19,20],commercialpap:[3,19,20,22],commercialpaperlegaci:19,commercialpapertest:22,commit:[2,7,14,16],commod:[],common:[3,4,6,14,15,18,19,20,21],commonleg:4,commonli:[],commun:[8,14,15],compani:13,companion:[14,19,20],compar:[6,19],compat:16,compel:2,compet:6,complementari:7,complet:[6,7,13,14,15,17,18,19,20,21],complex:[1,3,6,14,18,19],complic:[14,19,20],compon:[7,11,15],compos:[14,15,18,19,20],composit:20,compris:4,comput:[4,13],concept:[2,3,6,7,13,14,15,19],conceptu:[],concern:[6,14,19],conclus:[2,6,13],concreteclaus:20,concurrenthashmap:1,condit:[2,13,20,21],conf:5,config:12,configur:[5,8,12,14,17],confirm:[2,8],conflict:[2,6,9],confus:14,connect:[10,12],consid:[1,4,6,7,13,15,16,19],consider:19,consist:[4,6,13,14,15,20],constant:[1,19],constantli:13,constraint:[13,14,19],construct:[1,2,5,14,15,18,21,23],constructor:[7,14],consult:[],consum:[2,6,7,15,18],consumingtx:2,consumpt:[7,13],contact:[8,14],contain:[2,4,5,6,11,12,13,14,16,17,18,19,20,21,23],content:[1,2,5,6,7,8,12,13,14,18],context:[1,6,12,13,18],continu:[],contract:[],contractreject:21,contractst:[2,7,15,18,19,22],contractstateref:[],contrast:[6,13,14],contribut:18,control:[1,2,6,8,12,14,15,17,18,19,23],conveni:[1,6,18,19],convent:[4,14,20],convers:18,convert:[2,3,4,14,18,19],convinc:[14,18],copi:[1,2,6,11,14,19,21,23],copyonwritearraylist:1,copyright:1,corda:[],cordapluginregistri:5,cordapp:[],core:[3,6,13,14,15,18,19,21],corner:8,correct:[3,6,13,14,15,16,19,21],correctli:[6,13,15,19],correspond:19,correspondingli:1,cost:[13,19],could:[1,2,3,6,13,14,18,19],count:4,countabl:15,counter:[1,14],counterparti:[3,4],countri:[13,18],coupl:14,cours:[12,13,14,19,23],cover:[2,3,6,13,14,18,19,23],cp_program_id:[],crash:14,creat:[],createdummyir:4,createmessag:[],createsomenod:14,creation:[4,6,9,19],creator:13,credit:15,crisp:19,criteria:3,critic:[6,16],crop:6,cryptographi:[],curl:12,currenc:[3,4,14,15,18,19],current:[1,2,4,5,6,7,9,10,11,13,14,15,16,18,19,21,22],currentstep:14,currenttim:14,currentwallet:14,curv:4,custodi:[14,18],custom:[2,12,14,15,17,18],customis:23,cut:[],cycl:[1,14,19],dai:[2,4,12,13,14,16,18,22],daniel:15,danks:15,dashboard:12,data:[],databas:[6,10,14,18,19],dataset:4,date:[],dateoffset:15,daterollconvent:18,david:15,dead:11,deadlin:18,deal:[1,13,14,17,18,19],dealstat:18,debt:3,debug:14,decd098666b9657314870e192ced0c3519c2c9d395507a238338f8d003929de9:12,decd:12,decentralis:[6,13],decid:[8,13,19],decis:[2,6,19],declar:[1,21],dedic:1,defin:[1,2,6,10,12,14,15,18,19,20,21,22,23],definit:[2,14,18,19,20],delai:[4,13],deleg:[2,20],delet:[1,6,14,15,19],deliber:[6,21],deliv:[3,14,18],deliveri:[10,11,14,17],demand:[2,6,14],demo:[],demonstr:[15,17,23],denial:2,denomin:[],dens:1,depend:[1,2,6,7,8,13,14,15,19],dependencytxid:[],deposit:[19,21],depth:[],deregist:11,deriv:[4,14,18,19],describ:[1,2,6,7,9,14,18,19],descript:1,deserv:16,design:[1,2,6,9,10,13,19,20,23],desir:[14,18],desktop:12,despit:[14,19],destin:[],destroi:[3,6,19],destroypaperatredempt:22,destructur:19,detail:[],detect:1,determin:[3,4,7,20],develop:[1,5,6,10,14,15,16,17,19],devic:6,devis:6,diagram:[4,22],diamond:22,didn:[1,14,16,19],differ:[1,2,3,4,6,7,13,14,15,18,19,21],difficult:14,difficulti:20,digest:2,digit:[6,13,14,15,19],digitalsignatur:[2,13,14],direct:1,directli:[1,2,11,12,14,18,19,20],directori:[0,5,17,23],directthreadexecutor:1,dirti:19,disabl:18,disadvantag:6,discov:6,discuss:[6,14,18,19],disk:[11,14,15,18],disobei:13,displai:2,disprov:9,disput:[2,4,19],disrupt:11,distinct:[1,20],distinguish:[],distribut:[2,5,6,9,10,13,14],distrust:[2,14],divid:2,divis:18,dlg:[],doc:[0,1,9,15],docker:12,docsit:[0,16],doe:[1,2,3,4,5,6,7,10,12,13,14,19,21,23],doesn:[1,2,6,8,10,12,14,17,19,21],dokka:0,dollar:[18,19,21,22],domain:[15,18,19,22],don:[1,6,8,10,13,14,16,18,19,20,21],done:[0,6,14,15,19],dot:4,doubl:[6,10,14,17,19],doubt:[1,10],down:[1,6,14,19,20],download:[],downsid:[1,6],drag:22,drain:14,drive:[6,23],driven:17,driver:[15,23],drm:13,dsl:[15,21,22],due:[1,2,4,6,7,10,14,19,20],dummi:[3,14,21],dummy1:14,dummy2:14,dummy_cash_issu:21,dummy_notary_kei:14,dummy_pubkey_1:21,dummy_pubkey_2:21,dummycontract:14,duplic:14,durat:[7,13],dure:[1,4,5,14,15],dynam:[6,15,19,23],each:[1,2,4,5,6,7,13,14,15,16,19,20,21,23],earli:[1,3,22,23],earliest:[4,7],eas:[],easi:[1,6,13,15,19],easier:[1,14,19],easiest:19,easili:[1,14,19],econom:4,ed25519:15,edit:8,editor:8,effect:[4,6,14,21],either:[1,2,3,4,6,14,19,21,23],elbonia:18,element:[1,6,20],elimin:10,els:[2,6,13,14,18,19,20],email:14,emb:[],embed:[6,10,12,13],embedd:11,emit:[],empti:[2,15,19,21],emptyledg:21,emptyset:2,enabl:[5,20],encapsul:[1,18],enclos:1,encod:13,encount:[7,10],encrypt:[],end:[1,2,4,6,13,14,16,20,23],endpoint:[5,11,12],enforc:[1,6,19],enforceverifyorfail:21,engin:[],english:[1,19],enorm:14,enough:[1,8,14,19,23],ensur:[1,2,6,8,14,16,17,18,19,20],enter:[21,23],entir:[2,4,6,13,14,19],entireti:4,entiti:[2,6,13,18,19],entri:[4,5,6,14,19],enumer:4,environ:[1,5,13,14],envisag:19,equal:[2,14,18,19,20,21],equival:[1,4,18,19],especi:[18,22],essenti:[12,13,19,20],establish:[7,11,17],etc:[1,2,3,4,10,13,14,15,16,18,19,20],euribor:[12,13],euro:18,evalu:[4,13,20],even:[2,6,10,13,14,15,19,21],event:[],eventu:[2,16],ever:[1,6],everi:[2,6,11,13,14,15,16,19,23],everybodi:6,everyon:[2,13,19],everyth:[2,19,23],evid:13,evolut:6,evolv:[19,23],exact:2,exactli:[6,18,19],examin:[1,6,14,19],exampl:[],excel:13,except:[1,14,19],excess:1,exchang:[4,14,18],exclus:3,execut:[2,5,6,7,14,17,18,19],executor:1,exercis:[],exhaust:15,exist:[1,2,3,4,5,6,7,9,15,18,19,21,23],exit:[3,14,19],expect:[1,3,7,14,16,19,20,21],expectedtypenam:14,expectfailureoftx:[],expens:1,experi:[6,16,23],experiment:[1,14,15],explain:[1,7,14,15],explan:1,explicit:[1,6,14,19],explicitli:[1,6,21],explor:[1,6,8,9,10,12,14,19,23],exploratori:[],expos:[1,5,6,7,12,14,18],exposur:[3,4],express:[2,4,6,15,19,21],extend:[1,2,5,10,14,18,19,20],extens:[1,15,18,19],extent:6,extern:[14,23],extract:[6,12,13,18,19],extractcommand:20,extractgroup:[],extrem:[2,6],face:[19,22],facevalu:19,fact:[1,2,4,6,13,14,19,21],factor:[4,6],factori:[],fail:[19,20,21],failswith:21,failur:[14,21],fairli:[1,14],fake:[17,23],fals:[1,2,13,14,18,19],familiar:[6,19],famou:[6,15],fanci:19,far:[14,17,19],fashion:1,fast:[6,14,17],fault:14,featur:[1,6,11,13,22],feed:[2,13],feedback:15,feel:[19,23],fetch:[11,12,13],few:[1,10,12,13,14,16,17,19],fiber:14,field:[1,4,13,15,19,20,22],file:[0,1,5,6,12,13,14,15,16,17,18,23],fill:[1,14,17,19],filter:1,filterisinst:19,finalis:[2,4,14],finalisetransact:2,finalityprotocol:2,financ:[14,15,23],financi:[6,7,9,14,15,18],find:[0,6,10,12,14],fine:[6,21],finish:14,firewal:14,firm:[],first:[1,2,4,5,7,8,11,12,13,14,15,17,18,19,20,23],firstli:19,fit:[1,6],fix:[],fixabledealst:18,fixedleg:4,fixedlegpaymentschedul:4,fixedratepaymentev:4,fixingroledecid:7,fixingsessioninitiationhandl:7,fixof:13,flag:[12,23],flesh:18,flexibl:[2,6],flight:6,floatingleg:[4,7],floatinglegpaymentschedul:4,floatingratepaymentev:4,flow:[1,4,19,20],flux:23,fly:14,fold:1,folder:[0,5],follow:[0,1,2,5,6,7,8,9,12,14,17,19,20,21,22],font:1,foo:1,foobrokenexcept:1,fooutil:19,forc:[6,12,15,19,21],fordai:[7,13],forev:16,forget:[14,19],form:[2,6,7,17,19,20],formal:[],format:[0,1,6,12],forth:14,forward:[11,13,14,16,17],found:[8,12,13,14,16,18,23],four:19,fraction:18,frame:[1,14],framework:[],free:[2,6,14],freeform:[],freeli:13,frequenc:4,frequent:19,fresh:[13,19,21],freshkei:14,freshli:18,from:[0,1,2,3,4,5,6,8,9,10,12,13,14,15,16,17,18,19,21,22,23],fromcountri:18,front:19,frontend:10,frustrat:6,fulfil:[3,6],full:[1,2,3,11,14,19,20],fulli:[1,2,6,14,15,18],fullysign:14,fun:[2,7,13,14,19,20,21],fund:6,fundament:[2,6,9,19],fungibl:[3,18,19,20],fungibleasset:[],funni:[],further:[4,6,18,20],futur:[2,3,6,11,13,22,23],gain:10,game:[],garbag:[1,12,14],gather:19,gavin:6,gbp:[],gcd:6,gear:16,gener:[],generateiniti:14,generateirsandfixsom:4,generateissu:19,generatemov:19,generateredeem:19,generatespend:[14,19],genuin:1,get:[],getamount:21,getbefor:19,getbloomfilters:1,getclass:19,getclaus:[],getcommand:[19,20],getcontract:19,getdummy_cash_issu:21,getdummy_pubkey_1:21,getdummy_pubkey_2:21,getfacevalu:19,getfix:4,getifmatch:[],getifnotmatch:[],getinput:[15,19],getinst:15,getissu:19,getkei:19,getlegalcontractrefer:[19,20],getmaturityd:19,getmega_corp:21,getmega_corp_pubkei:21,getnotarysignatur:[2,14],getoutput:[15,19],getoutst:15,getown:[19,20],getparticip:19,getprogramref:[],getprotocoltrack:14,getrequiredcommand:20,getsign:[19,20],getter:19,gettim:[],gettimestamp:19,gettimestampbi:[],gettransact:14,getvalu:[19,20],git:[8,16],github:0,giusepp:15,give:[2,6,11,14,19],given:[2,6,13,14,19],givenpric:14,global:[1,2,6,15,18],glue:14,gnu:0,goal:[1,6,9,10,16],goe:17,gone:[14,15,19],good:[1,8,14,19,21,22,23],got:[12,14],gover:19,grade:18,gradl:[5,8,16,19],gradlew:[8,17],grammar:1,granular:6,graph:[6,10,12,14,22],graphit:12,great:15,greater:1,greatest:6,green:8,groom:6,group:[],groupclaus:20,groupclauseverifi:20,groupingkei:20,groupstat:[19,20],guarante:[16,18],guava:[1,19],gui:14,hack:[6,15],had:[2,14,15,18,19],hand:[7,14,19],handa:15,handi:14,handl:[1,2,3,6,14,15,19,20],handler:[5,7,14],happen:[1,2,6,7,13,14,21],happi:17,hard:[1,6,14,16],harder:[6,19],hase:4,hash:[2,6,10,12,13,14,18,19],hashcod:19,hasn:8,hassl:14,hat:16,have:[1,2,3,4,5,6,7,8,10,11,13,14,15,16,17,18,19,20,21,23],haven:19,heap:14,hearn:6,heart:19,heavi:16,heavili:6,hedg:[3,4],heirarchi:1,held:[],hell:14,hello:14,help:[1,6,7,14,19],helper:[4,14,18,19],henc:[2,4,6],her:[19,22],here:[1,2,6,10,12,13,14,15,18,19,21,22,23],hidden:11,hierarch:14,hierarchi:14,high:[6,14],higher:[1,2,8],highlight:15,histori:2,hit:[6,8],hoc:15,hold:6,holder:[1,6,19],holidai:[4,13,18],home:[8,17],hood:21,hopefulli:23,hospit:14,hotspot:1,hour:14,how:[],howev:[2,3,4,6,13,14,18,19,20,21],html:[0,1],http:[0,8,12,13,14,17,19,20,23],hub:14,human:[2,6,13,14],hundr:14,hurt:14,hypothesi:9,idea:[1,6,8,10,14,23],ideal:[14,19],ident:[2,6,11,13,14,18,19,20,21],identifi:[4,6,11,12,13,14,18],identityless:6,identityservic:[],ifmatch:15,ifnotmatch:15,ignor:[14,19,20],illeg:[],illegalargumentexcept:[1,14,19,20,21],illegalstateexcept:[1,19,20],illustr:1,imagin:[1,14,19],immedi:6,immut:[1,4,6,13,19],immutablelist:19,imper:1,implement:[],impli:14,implic:[2,6,14],implicitli:4,impos:[13,19],imposs:[6,13],improv:[6,15,16,19,20,22],inbackground:[],includ:[],incompat:21,inconveni:19,incorpor:13,increas:1,indent:1,independ:[2,13,20],index:[4,6,7,8,16,19],indexsourc:7,indic:[1,4,7,14,15,19],individu:[1,17,19,21],indivis:18,industri:[9,10,12],infer:21,infix:[],influenc:12,info:14,inform:[1,2,6,14,18,19],infrastructur:[6,10,12,14,19],inher:6,inherit:[1,19,20],init:[],initi:[2,14,15,23],initialis:14,inmemorymessagingtest:[],inner:20,inoutgroup:[19,20],input:[2,3,6,13,14,15,19,20,21,22],inputcash:21,inputindex:2,insert:[1,2,12,13,14],insid:[6,14,17,19],instal:[0,8],installdist:17,installtemplatenod:5,instanc:[],instant:[1,7,14,18,19],instanti:[6,7,14,15],instat:21,instead:[1,6,10,11,14,15,17,18,19,23],instig:2,institut:6,institutionrefer:[],instruct:12,instrument:[3,4,7],insuffici:6,insufficientbalanceexcept:19,integ:[15,18,19],integr:[1,6,13,14,15,22],intellig:1,intend:[1,3,6,12,13,14,18,21],intent:[13,19,22],intention:1,inter:15,interact:[1,6,11,13,14,15,19],interchang:18,interest:[],interestrateswap:[],interfac:[],intern:[1,11,14,18,19],internalis:1,interop:[10,19],interpol:18,interpret:[1,6],intersect:19,interv:18,intesa:15,introduc:[1,2,7,13,15,19],introductori:9,intuit:1,invalid:[2,13,14,18,19],invari:19,investig:14,invoc:14,invok:[1,6,7,12,14,15],invokeprotocolasync:14,involv:[2,3,6,14,18,19,23],ipsa:13,irrelev:7,irsdemo:17,irsexport:4,irstest:4,irsutil:4,irswebdemo:17,isbefor:19,isempti:19,isinst:14,isn:[1,6,14,18,19,23],isol:20,issu:[2,3,6,13,14,15,16,18,19,20,21,22,23],issuanc:[3,18,19,20,22],issuedbi:21,issuer:[3,6,14,18,19,21],item:19,iter:[14,16,19],itself:[2,4,6,7,11,12,13,14,19,21],jar:[0,5,6,12],jarinputstream:[],java:[1,5,6,7,10,12,14,15,18,19,20,21,23],javaclass:14,javacommercialpap:19,javadoc:[1,5],javatesthelp:21,jdk1:8,jdk:[8,15,18,19],jetbrain:[8,10],jmx2graphit:12,jmx:12,jmxtran:12,job:[14,23],johann:15,join:[11,19],joint:[],jolokia:12,json:[12,23],judgement:1,jump:17,junit:[],just:[1,6,8,11,12,14,15,18,19,21,23],justifi:9,jvm:[5,6,10,12,14,23],kafka:[],kdoc:1,keep:[6,14,19,22],kei:[1,3,6,10,13,14,18,19,21],kept:14,key_mismatch_at_issu:[],keymanagementservic:14,keypair:[14,19],keyword:[1,21],kick:14,kind:[6,13,14,18,19,23],know:[2,6,7,10,13,14,17,19,20,21],knowledg:13,known:[],kotin:[],kotlin:[],kryo:14,label:[14,21,22],labori:[],lack:[],lambda:21,land:4,lang:21,languag:[1,5,6,8,9,10,14,15,18,19,22,23],larg:[6,11,13,14,15,18,19,23],larger:[1,6],last:[14,16,21],lateinit:14,latenc:2,later:[1,10,13,14,15,18,19,20],latest:[1,8,15],latter:[1,19],launch:7,layer:[6,11,13,14],layout:22,lead:[1,6],leak:[2,6,14],learn:[6,9,14,17,18,19,23],least:19,leav:[1,14],ledger:[2,3,4,6,9,12,13,14,15,18,19,21,22],ledgertransact:[14,18],left:[14,17,20,21],leg:[4,7],legal:[2,6,13,18,19],legalcontractrefer:[19,20],legallyidentifi:[2,13,14],legallyidentifiablenod:[],less:[14,22],let:[1,6,7,11,12,13,14,15,17,18,19,21],letter:[1,11],level:[1,2,4,8,11,14,18,19,20,21],lib:[0,5],liber:1,libor:[4,12,13],librari:[1,12,13,14,18,19],licens:1,life:[14,19,23],lifecycl:[],lifecyl:3,lifetim:4,lightweight:14,like:[1,2,4,6,7,8,11,12,13,14,16,18,19,20,23],likewis:19,limit:[3,6,9,19],line:[],linear:18,linearst:18,liner:1,link:[1,6,13,14,18],linkabl:6,linkag:6,linux:[12,15],list:[0,2,6,13,14,15,16,17,19,20],listen:1,listenablefutur:[2,14],listof:[14,19],liter:6,littl:[1,14,19,21],live:[4,14],livelock:6,load:[2,6,14,15,17,18,19,23],loan:[3,4,13],local:[0,6,8,12,14,21],locald:13,localhost:[12,17],locat:[5,18,19],lock:[1,3],log4j:15,log:[14,15,17,20],logger:14,logic:[2,6,7,11,14,15,18,19,20,23],longer:[1,4,14,15],look:[1,4,11,12,13,14,16,18,19,20,21,23],loop:[1,4,19],loquitur:13,loss:13,lot:[1,4,6,17,19,23],low:[2,14],lower:1,lowest:11,lurch:14,mac:12,machin:[],maco:[],made:[1,4,6,9,14,15,16,18],mai:[1,2,5,6,9,11,12,13,14,15,16,18,19,20,21,23],mail:[16,17],main:[7,11,14,17,22,23],mainstream:10,maintain:[2,6,19],maintan:13,mainten:11,major:[14,16],make:[0,1,2,4,6,13,14,15,17],makenod:[],maker:10,maketransact:14,malici:14,manag:[],mandatori:19,mani:[1,2,5,6,7,13,14,15,18,19],manipul:18,manner:[6,14,19],manual:[2,5,7,14],map:[],mappabl:19,mark:[1,3,14,19],markdown:1,marker:14,market:9,master:[9,16],match:[6,14,20],matchbehaviour:[],math:[],mathemat:18,matter:19,matur:[2,3,4,12,13,19],maturityd:19,maven:[8,19],maximis:6,maximum:6,maybestx:14,maybetraderequest:14,mbean:12,mean:[1,2,6,7,13,14,18],meaning:[2,3],meant:14,measur:4,mechan:15,meet:19,mega_corp:[14,21],mega_corp_kei:14,mega_corp_pubkei:[21,22],megacorp:[14,22],member:[4,15],memori:[],menlo:1,mention:[7,14],menu:8,mere:4,merg:[6,15,18,19],mergeabl:19,mess:14,messag:[],messagehandlerregistr:[],messagerecipi:[],messagerecipientgroup:[],messagingservic:11,method:[],metric:12,micro:20,mid:2,middl:[1,14],might:[1,4,6,8,13,14,19],mike:6,mileston:[],mind:[1,13,14],mine:6,miner:6,mini:[],mini_corp_pubkei:14,minim:[6,14],minimis:[2,3,6,11],minimum:[4,6],minor:16,minu:19,minut:[10,13,14],misc:[],mismatch:[6,19,21],miss:[1,14,19,21,23],missingsig:14,mission:12,mix:[1,14],mock:14,mocknetwork:14,mocknod:14,mockservic:18,mode:[],model:[],modest:6,modif:[18,19],modifi:[2,3,4,8,14,18,19,20],modul:[1,14,15,19],moment:[14,15],monei:[13,19],monetari:[],monitor:[],month:[4,14,16],more:[1,2,3,4,5,6,10,12,13,14,15,17,18,19],moreexecutor:1,mortensen:15,most:[1,4,6,12,14,19],mostli:19,move:[3,6,14,15,16,19,20,21,22],movement:[14,19],much:[1,6,10,14,15,19,23],multi:[1,11,14],multilater:[3,15],multipli:4,must:[1,2,3,5,6,7,12,13,14,17,18,19,20,23],mustafa:15,mutabl:[1,6,18,19],mutat:6,mutual:[2,3,14],myfil:12,mykei:18,mykeypair:14,mysql:10,nail:1,namedbyhash:[],namespac:14,narrow:1,nativ:14,natixi:15,natur:19,naval:2,navig:[5,17],navistar:2,neat:21,necessari:[1,2,16,17],necessarili:18,nee:15,need:[0,1,2,4,6,7,9,12,14,16,17,18,19,20,21,23],neg:18,negoti:[6,18],neither:14,nest:14,net:[3,4,14,15,19,22],nettabl:[],network:[],neutral:10,never:[1,2,6,19],newli:7,newnotari:2,newown:19,newsecurerandom:15,next:[1,4,7,8,14,15,19],nextfixingof:7,nextscheduledact:7,nice:[13,19],nio:1,nix:[],noddi:12,node:[],node_dir:5,nodea:[5,17],nodeb:17,nodeinfo:14,nodeinterestr:13,nodej:17,nodeservic:13,non:[],none:[7,14,20],nonemptyset:15,nordea:15,normal:[2,3,4,14,18,19,20],not_matured_at_redempt:[],notabl:1,notaris:[2,6,14,18,19],notarychang:15,notarychangeprotocol:2,notaryexcept:2,notarynod:14,notaryprotocol:[2,14],notaryservic:15,notarysig:14,notarysignatur:14,notarytous:18,notat:14,note:[],noth:[1,6,7,14,15,19],notic:1,notif:11,notifi:[2,11],notion:[4,6,19],notnul:[19,20],now:[1,5,6,8,14,15,17,18,19,21,22,23],npm:17,nugget:19,nullpublickei:19,number:[1,3,4,6,13,14,16,17,18,19],numer:6,obj:19,object:[1,3,4,6,7,10,11,12,13,14,15,18,19,20,22,23],oblig:[],obligor:3,observ:[2,4,6,7,14],observatori:2,obsolet:7,obtain:[],obviou:[1,2,6,13],obvious:4,occasion:[],occur:[2,7,14,19],occurr:2,odd:19,off:[14,22],offer:14,offlin:11,offset:4,often:[1,3,4,6,13,14,19],oftenor:13,oil:[15,21],old:[2,14,19],omit:7,onc:[0,1,2,4,5,7,14,16,18,19,23],onchainasset:3,onledgerasset:19,onli:[1,2,4,5,6,7,10,11,12,13,14,15,16,18,19,20,22,23],onto:[1,14,19,22],opaqu:[],opaquebyt:[],open:[2,6,8,14,17,22],openjdk:8,oper:[4,7,12,13,14,18,19],optim:1,option:[0,1,4,7,14,19,20,23],oracl:[],orchestr:[9,10,15,23],ordain:4,order:[0,1,2,3,4,6,10,13,14,18,20,22],ordinari:[6,14,19],org:[0,8,17,19,20],orient:[],origin:[18,19],originalst:2,otc:[],other:[1,2,3,4,5,6,7,10,13,14,17,18,19,20,21],othersid:14,otherwis:[1,7,14,19],our:[1,2,6,7,14,15,16,19,21],ourselv:[14,19,23],oursignatur:14,out:[1,2,3,6,7,8,11,12,13,14,16,18,19,20],outag:[],outcom:14,outer:20,outermost:20,outlin:[6,9,14],outpoint:6,output:[2,3,5,6,13,14,15,19,20,21,22],outref:14,outsid:[5,6,13,14,23],outstand:3,outstat:[],over:[1,2,4,6,11,12,13,14,18,19],overal:[2,7,21],overdu:7,overflow:1,overload:[14,18],overnight:18,overrid:[7,14,19,20],overwhelm:6,own:[1,2,3,5,7,12,13,14,15,16,18,19,21,22,23],ownablest:[14,18,19],owned_bi:[],owner:[7,14,18,19,20,21],ownership:[14,19],owningkei:[14,19],ozturk:15,p2p:15,pack:19,packag:[15,18],packet:6,page:[8,13,16,17],pai:[3,22],paid:[3,4,6],pair:[6,14,18,19],paper:[],paper_1:22,parallel:[6,13],parallelis:6,paramet:[1,7,14,17,18,19,20],parameteris:6,parent:14,pars:[13,18,23],part:[1,2,3,6,7,14,15,18,23],parti:[],partial:[2,6,14,19,21],partialtx:14,particip:[2,6,15,19,23],particular:[1,2,6,12,14,15,18],partyandrefer:[1,19],partynod:14,partyrefer:[1,19],pascal:1,pass:[2,14,19,20,22],past:[1,17,19,23],patch:1,path:[1,7,11,12,15,19],pattern:[1,6],paye:6,payer:[4,6],payment:[3,4,6,7,13,14,17,19,22],pdf:13,peer:[10,13,14,19],penni:[18,19],peopl:[1,6,10,14,19],per:[1,6,7,23],perform:[1,2,4,6,7,13,14,17,19,20],perhap:[1,6,11,19],period:4,perman:19,permiss:10,persist:[5,10,11,14,15],perspect:[6,14,19],phrase:13,physic:[2,15],pick:[11,14,15,16,19,23],piec:[1,2,6,14,18,19,21],ping:[],pip:0,pki:[6,15],place:[0,1,4,6,7,10,11,13,14,15,16,18,19,23],plai:6,plan:[6,13,14,17],platform:[],pleas:[1,6,8,15,17],plu:18,pluggabl:15,plugin:8,point:[1,2,3,5,6,12,13,14,16,19],pointer:[2,14,18],pointless:1,pong:[],pool:[1,6],poor:6,pop:8,popular:10,popup:8,port:[15,16,17],posess:14,posit:[1,2,6,14],possess:2,possibl:[6,13,14,19],post:[],postgr:10,potenti:[1,2,10,14,19],pound:[18,19],power:[6,9],practic:[6,19],pre:[0,4,14,19,21,23],preced:19,precis:[2,6,10],precondit:[1,19],prefer:1,prefix:[1,14],preliminari:[],prepar:[6,19],present:[2,3,4,9,10,14,18,19,20],preserv:[2,6],press:[],pretend:[12,18],pretti:[6,14],prevent:19,previou:[6,14,15,18,21],previous:[4,7,13,15],price:[6,13,14],primari:13,primarili:3,primit:21,print:17,priv:14,privaci:[1,2,6,10,14,15,19],privat:[1,6,14,19,23],privatefoo:1,probabl:[8,19,23],problem:[2,6,13,14],proce:14,procedur:[14,19],process:[],processor:6,produc:[0,7,19,21,22],product:[1,7,9,10,16,18],profit:22,profound:6,program:[1,6,12,15,17,18,19,23],programref:[],progress:[],progresstrack:14,project:[8,15,17,19],prolif:15,promis:15,proof:[3,6,9],propag:[9,12,14,19,20],properli:14,propos:[9,14],prose:[13,18,19],protect:14,protocol:[],protocollog:[7,14],protocollogicref:[],protocollogicreffactori:7,protocolstatemachin:[],protocoltrack:14,prototyp:[1,9,10,13,19],prove:[2,6,9,19],provid:[0,1,2,3,4,5,6,11,12,13,14,15,18,19,20,23],provision:18,pseudo:13,pseudonom:18,ptx:[2,14],pubkei:21,publicfoo:1,publickei:[],publicli:[],pull:8,pump:[],punish:13,purchas:[14,17],pure:[3,6,13],purpos:[2,3,14,18,19],push:16,put:[1,14,23],python:0,qualiti:9,quantiti:[6,18,19],quasar:14,queri:[4,7,13],question:[1,2,7,8,13],queu:11,queue:[1,11,14],quick:13,quickli:[6,19],quit:[1,2,14,19],r3corda:[15,17,19,21],r3dlg:16,r3prototyp:[0,8,17],r3repositori:8,rais:[2,20],random63bitvalu:14,random:[6,7,15,18],rang:2,rapid:[1,10,16],rare:18,rate:[],ratefixprotocol:[],rather:[1,6,11,14,15,19,20],raw:[11,12,14],reach:[2,4,6,7,13],reachabl:14,read:[1,6,9,10,12,14,19,23],readabl:[10,14],reader:[],readi:[2,14,16,19],readili:[18,20],readm:1,real:[1,13,15,18,19,23],realis:14,realism:[],realist:18,realiti:4,realli:[1,2,6,14,19],reason:[1,2,4,6,14,18,19],reassign:19,recal:4,receiv:[3,4,6,13,14,16,19,22],receiveandcheckproposedtransact:14,receiveandvalidatetraderequest:14,recent:15,recipi:[3,6,19],recognis:[6,14,19],recommend:[1,11,23],record:[2,7,14],recordtransact:14,recov:[],recreat:14,red:[4,8],redeem:[3,19,20,22],redempt:[19,22],redemptiontim:22,redesign:15,reduc:[1,19],redund:1,ref:[14,18,21],refactor:15,refer:[1,2,3,4,6,7,13,14,15,18,19,21],referenc:2,refin:[],reflect:[9,14,19,20],refus:8,regard:2,regardless:14,regener:[4,16],regist:[1,5,11,12,14,23],registr:[],regular:[12,14,18,19],reissu:19,reissuanc:6,reject:19,rel:[6,20],relabelablestep:14,relat:[4,7,18,19],relationship:19,releas:[],relev:[6,7,15,18,19,20],reli:6,reliabl:[],relianc:6,relic:12,religi:1,remain:[7,14,19,22],remeb:8,rememb:[1,7,8],remind:14,remot:8,remov:[14,16,19],renam:[14,15],render:[1,14,22],repeat:[1,4,14],replac:[2,4,8,12,15,16,18,19],replic:6,repoint:2,report:[14,20],repositori:[],repres:[1,3,4,6,13,14,18,19],represent:4,request:[2,6,11,13,14,15],requestingparti:2,requiredcommand:[15,20],requiresinglecommand:[19,20],requirethat:[19,20],research:15,resel:13,reserv:14,reset:4,reshap:6,resolut:[2,6,9,14],resolv:[1,14,18,19],resolvefromtwohash:14,resolvetransactionsprotocol:14,resolvetransactionsprotocoltest:14,resourc:[6,14,17],respect:[1,6,14,17],respend:6,respons:[2,6,7,11,14],rest:[2,6,10,12,14,15,23],restart:[8,14],restor:14,restrict:1,restructur:20,restructuredtext:0,result:[1,2,4,6,13,14,19,20],resultfutur:[],resum:[14,15],resurrect:14,retain:11,retri:[10,11,14],retriev:[2,4,14],retrieveoutput:21,reus:[6,21],reusabl:[13,15],reveal:[2,6,14],revers:14,revert:3,review:[1,15,16],revis:4,rewrit:14,richer:5,right:[1,8,12,14,16,23],rigid:6,rigidli:1,risk:14,robert:15,robust:15,role:[6,7,17,23],roll:[4,14,17],rollov:[18,19],root:[16,17,22],rotat:15,roughli:[2,16],rout:[11,14],router:[],row:[18,19],rui:15,ruin:21,rule:[1,13,14,15,19],run:[],runbuy:[],runnetwork:14,runsel:[],runtim:[1,14],safe:[1,6,14],safeti:1,sai:[1,2,6,19],sale:[17,19],same:[1,2,3,4,5,6,7,13,14,17,18,19,20,21,22],sampl:[5,14],sandbox:[6,7,10],saniti:14,santiago:15,satisfi:19,save:[1,14,15,19],scala:[10,19],scalabl:[1,6],scale:4,scenario:[6,23],scene:[14,19],schedulablest:7,scheduledact:7,scope:[6,20],scotiabank:15,scrape:12,scratch:[18,23],screen:[1,8],script:[0,6],scroll:17,scrub:14,seamless:10,search:[8,19],second:[4,14,17,18,19],secondari:14,secp256r1:15,section:[6,16],secur:[6,7,11,14,18],securehash:[2,18,19,20],securerandom:15,see:[0,1,2,3,4,7,13,14,17,18,19,20,23],seed:14,seek:6,seem:6,seen:[1,4,13,14,19,22],select:[2,8,15,19,20],self:[5,15],sell:[14,19,23],seller:[],sellerownerkei:14,sellersig:14,sellertradeinfo:14,semi:6,send:[1,2,6,11,12,13,14,16,19,21],sendandrec:14,sender:[6,14],sendsignatur:14,sens:[4,13,19],sensit:7,sent:[7,14,18,19],separ:[2,5,6,11,12,13,14,17,18,19],sequenc:6,sequenti:14,seri:14,serial:[10,19],serialis:[1,6,10,14,19],serializablewithkryo:[],serializeablewithkryo:[],seriou:[6,16],serious:23,serv:5,server:[5,10,11,12,19,23],servicehub:[2,5,11,14],servicehubintern:[2,5],session:[7,11,14],sessionid:[7,14],set:[],setof:[14,20],setter:19,settim:[14,18],settl:[3,14,18],settlement:[3,14],setup:[5,7,14],setupa:17,setupb:17,sever:[5,6,14,19,21,23],sha256:[18,19,20],sha256sum:12,sha:[6,12],shape:6,share:[3,4,6,13,14,15,19,23],shasum:12,she:19,shortcut:10,shorthand:21,shot:[],should:[1,2,3,5,6,7,8,10,14,15,17,18,19,20,21,23],shoulder:1,shouldn:[14,19],show:[6,8,10,17,22],shown:[14,18],shutdown:14,side:[6,7,13,14,18],sig:19,sign:[2,4,6,10,11,13,14,15,18,19,20,21],signatureexcept:14,signaturesfromsel:14,signedtransact:[2,14,18,19],signer:[13,19,20],signific:[6,15],significantli:[4,18],signoff:2,signwith:[14,18,19],signwithecdsa:14,signwithourkei:14,silver:1,similar:[1,6,14,15,19,20],simpl:[1,3,4,6,10,12,14,18,19,20,22],simplecash:21,simplecashdoesntcompil:21,simplecashfailswith:21,simplecashsuccess:21,simplecashtweaksuccess:21,simplecashtweaksuccesstopleveltransact:21,simplenotaryservic:2,simpler:[6,10],simplest:[6,14,19,23],simpli:[1,6,11,14,18,19,21],simplif:15,simplifi:[1,3,6,18,19,23],simultan:[6,14,18,19],singl:[],singleclaus:[],singlemessagerecipi:[11,14],singleton:[14,19,20],singletonlist:[],sit:[],site:[1,16],situat:[1,6],size:[1,4,6,14,19,20],skeleton:14,skip:[14,18,19],slf4j:14,slight:[],slightli:19,slip:16,slow:[1,6],slowest:6,small:[6,7,13,14,17,19,22],smaller:[15,20],smallest:18,smart:[],smm:[],smooth:19,snake:21,snapshot:[6,15,16],snide:0,snippet:[2,14],softwar:[6,14,16,23],sofu:15,sold:[14,18,22],solut:14,solv:[6,13,14],solvenc:13,some:[1,2,3,6,7,10,12,13,14,15,17,18,19,20,21,22,23],somed:19,someon:[2,6,19],someprofit:22,someth:[1,4,6,8,14,17,19,20,23],sometim:[6,12,14,18],somewhat:[6,14,15],somewher:22,soon:19,sophist:6,sort:[13,14],sound:[1,14,19,22],sourc:[4,7,8,13,14,19],sparingli:1,special:[2,6,14,21],specialis:[],specif:[2,3,5,6,7,11,12,14,15,18,19,20,22],specifi:[0,1,2,3,5,6,10,14,15,20,21,23],speed:[6,14],spend:[6,10,14,19],spent:[6,19,21],sphinx:0,sphinx_rtd_them:0,spirit:15,spline:18,split:[6,11,15,18,19,20],splittabl:19,spread:[2,14],spreadsheet:13,sql:10,squar:22,src:[17,22,23],ssl:15,stabilis:16,stabl:16,stack:14,stage:[1,3,14,19,23],stai:[6,19],stake:6,standalon:13,standard:[1,5,9,12,14,18,19,20],standardis:[6,18],start:[],startprotocol:[2,14],state:[],stateandref:[2,14,18,19],statehistori:2,stateless:6,statemachinemanag:14,statement:[1,6,13,14,19],stateref:[2,6,7,18],statesoftyp:[14,19],statist:12,status:6,step:[],still:[2,6,7,13,14,15,19,23],stock:[6,13],stop:[1,14],stopnod:14,storag:[6,14,18],store:[2,5,14,15,19],stori:[1,15],straightforward:[14,19],stream:[11,14],stress:1,strictli:[4,6],string:[13,14,18,19],strip:19,strong:10,structur:[1,6,8,10,13,14,18,19],studi:19,stuff:1,stx1:14,stx2:14,stx:[14,18],sub:[1,14],subclass:[3,14,18,19],subclaus:20,subgroup:6,submiss:13,submit:[1,2,11,14,17],subprotocol:2,subscrib:11,subsequ:21,subset:3,subsystem:11,subtask:14,subtl:[1,6],subtract:18,successor:[2,7,10],succinct:1,sudo:[0,17],suffer:6,suffic:14,suffici:[6,9,13,16,18],suffix:[],suggest:[11,19],suggestinterestrateannouncementtimewindow:7,suit:15,suitabl:[7,11,16,20],sukrit:15,sum:[19,21],sumcashbi:[14,19],sumcashornul:[],summari:[],summaris:6,sun:1,superclass:[3,15,18],superior:1,supersed:6,supertyp:19,suppli:[3,17],support:[],suppos:[14,19],suppress:[1,15],suppresswarn:1,sure:[2,15,16,17,19,23],surfac:14,surround:1,surviv:14,suspend:[],swap:[],swapping_signatur:14,swapsignatureswithsel:14,symbol:8,sync:19,synchronis:[1,2,6],syntax:[10,19],system:[2,5,6,10,12,14,15,17,19],tab:[1,8],tackl:[15,20],tag:[1,16],tailor:9,take:[1,4,7,10,14,16,18,19,20,21,22],taken:19,talk:14,tamper:14,target:[0,1,6,10,12,14],targetrecipi:[],task:[5,6,7,14],team:8,teardown:14,technic:[],techniqu:[1,6,10,13],tediou:19,tell:[0,14],templat:5,tempor:[],temporari:[],temporarili:[14,16],tempt:19,temptat:[],ten:19,tenor:[4,12,13,18],term:[3,6,7,11,18,20],termin:[4,12,14,17],terminolog:6,test:[],test_tx_tim:[],testutil:[],testwithinmemorynetwork:[],text:[1,8,12,21],than:[1,2,5,6,9,11,12,14,15,19,20,22],thank:15,thedao:15,thei:[1,2,3,4,5,6,7,12,13,14,16,17,18,19,20],theirsessionid:14,them:[1,2,4,6,7,8,10,11,12,14,15,16,17,18,19,20,21,23],themselv:[11,13,14,18,19],theori:[],therefor:[6,8,10,14,16,19],thi:[0,1,2,3,4,5,6,7,8,9,12,13,14,15,16,17,18,19,20,21,22,23],thin:11,thing:[1,6,7,10,13,14,15,17,18,23],think:[1,6,8,11,14,19],third:[6,17],thisstateref:7,thorough:14,those:[2,6,7,12,14,17,19],though:[12,14,19],thought:[6,10],thousand:21,threadsaf:1,three:[14,17,18,19],threshold:[],through:[4,6,7,11,12,14,15,19,20,21,23],throughput:[2,6],throwifsignaturesaremiss:14,thrown:[14,19],thu:[1,2,6,7,12,13,18,19],ticket:14,tidi:14,tighten:19,tightli:14,time:[1,2,3,4,6,7,12,13,14,15,17,18,22],timelin:19,timem:19,timestamp:[],timestampauthoritysig:14,timestampcommand:[],timestampercli:[],timestamperservic:[],timestampingauthor:[],timestampingprotocol:[],titl:8,todo:[1,14,19],togeth:[3,6,15,19,20],token:[14,18,20],told:1,toledgertransact:18,toler:[2,7],tolist:[],too:[1,14,19,22],took:14,tool:[10,11,12,14],toolbar:8,top:[1,6,8,11,14,17,20],topic:[11,14,19,23],topicsess:[11,15],toplevel:21,topriv:14,toset:[],tosignedtransact:[2,14,18,19],tostr:[1,14,19],tostringsshort:14,total:6,toward:[15,16],towiretransact:18,trace:[14,20],track:[],tracker:14,trade1:17,trade:[],trade_top:[],tradeoff:[],trader:[],traderdemo:23,traderequest:14,tradit:6,traffic:6,transact:[],transactionbuild:[2,14,15,18,19],transactionforcontract:[19,20],transactionforverif:19,transactiongroup:[],transactiongroupdsl:22,transactiongroupfor:22,transactiongroupfortest:[],transactionst:[2,15,18],transactiontyp:[14,15],transactionverificationexcept:21,transfer:[19,21],transit:[9,19,23],transmit:[],treat:19,tree:14,tri:[6,19],tricki:[6,14],trigger:[2,3,7,13,14,17,20],trim:20,trivial:[1,6],trust:[3,6],truth:14,tsa:[],tsasig:[],tupl:1,ture:6,turn:[6,14,18,19,20,21,23],tutori:[3,9,10,13,14,15,19,20,21,23],tweak:21,twice:21,two:[],twopartydealprotocol:7,twopartytradeprotocol:14,txb:18,txbit:14,txhash:[6,14,19],txt:12,type:[],typenam:14,typeonlycommanddata:19,typetobui:14,typic:[6,7,11,12,14,18,19,23],ugli:14,unaccept:14,unacceptablepriceexcept:14,unavoid:14,under:[0,5,16,18,19,20,21,23],underli:[3,4,6,14,18],underscor:1,understand:[6,12,19,20,22,23],unexecut:[],unexpect:14,unfinish:14,unfortun:[14,19],unguess:[],unicredit:15,unifi:[15,23],uniform:7,unindex:8,uniqu:[2,6,13,14,15,18],uniqueidentifi:[],unit:[8,22,23],unix:[12,17],unknow:2,unknown:18,unless:[1,13,14,16,19,23],unlik:[3,8,19],unmatch:[],unnatur:6,unnecessari:[],unpack:[14,19],unprocess:20,unqiu:7,unread:14,unrecognis:19,unrel:19,unreleas:[],unschedul:7,unserialis:14,unset:4,unspent:6,unstart:14,unsupportedoperationexcept:19,until:[2,4,6,7,14,16,21,23],untrust:14,untrustworthydata:14,unus:[],unusu:[],unverifiedtransact:21,upcom:[7,15],updat:[6,8,11,14,15,16,19],upgrad:[8,9,14,15,19],upload:[],upon:[4,14,19],upward:16,url:[8,17],usabl:[15,16],usag:[1,13,14,19],usd:[],useless:19,user:[0,1,6,8,10,13,14,15],usr:0,usual:[1,6,16,19],utc:7,util:[2,15,18,19],uuid:18,vagu:1,val:[1,2,7,13,14,18,19,20,21,22],validatedtransact:14,validatingnotaryservic:2,valu:[1,2,3,4,6,13,14,15,19,20,21,22],valuabl:13,valuat:4,vanilla:[3,4],vari:[],variabl:[1,4,6,14,19],variant:19,variou:[1,6,12,14,19],vehicl:6,vendor:[10,12],verbos:19,veri:[1,3,6,10,13,14,19,21,22,23],verif:[3,6,10,20,21],verifi:[],verifyclaus:20,verifysignatur:14,verifytransact:[],versa:[3,4,6,14,18],version:[4,8,11,13],versu:14,vertic:1,via:[0,1,4,6,7,11,12,13,14,17,23],vice:[3,4,6,14,18],view:[1,4,17],virtual:[6,9],visibl:[2,6],vision:9,visualis:[],vital:14,wai:[1,2,5,6,7,11,12,13,14,15,19,21,23],wait:[7,8,14,17],wake:15,wallet:[6,7,14,15,19],walletservic:14,want:[1,6,8,12,13,14,15,18,19,21,23],weak:[13,18],wear:16,web:[],websit:[],websocket:14,weekend:4,well:[0,1,2,4,6,7,10,12,14,19,20],went:1,were:[1,6,13,14,19],what:[],whatev:[1,14,18],when:[1,2,3,4,6,7,11,12,13,14,15,18,19,21],whenev:1,where:[],wherea:4,wherev:12,whether:[2,3,13,14,18,20],which:[0,1,2,3,4,5,6,7,9,10,11,12,13,14,15,16,17,18,19,20,21,23],whilst:[6,13,14,17,19],whitelist:[3,5,7,14],whitepap:9,who:[1,6,10,14,15,18,19],whole:[2,21],whom:[3,6],whose:[3,12,18],why:[1,6,10],wide:1,widescreen:1,widespread:1,width:1,wiki:[6,19,20],wikipedia:[19,20],window:[2,6,8,14,17,22],wire:[14,23],wirecommand:[],wiretransact:[2,13,14,18],wish:[6,13,14,15,18,19,23],within:[0,1,2,6,12,17,21],withitem:[18,19],withkei:14,withnewown:[14,19],without:[],withoutissu:[14,19],withoutown:[19,20],withown:19,won:[11,13,14,19,21],word:[1,2],work:[1,2,4,5,6,7,8,9,10,12,13,14,15,17,18,19],worker:1,world:[6,13,14,19,21],worn:19,worri:[1,10,14,19],worst:6,worth:[1,19],worthless:13,would:[1,2,3,4,6,10,12,13,14,18,19,20,23],wouldn:13,wrap:[1,11,12,14,15,18,19,20,23],wrapper:[1,2,14],write:[],written:[0,4,6,10,15,19],wrong:[1,14,17,21],wrote:6,wtx:[2,13,14],www:[0,8],year:[4,14],yet:[1,2,4,6,10,14,15,18],yield:6,you:[0,1,2,5,6,7,8,10,11,12,13,14,15,17,18,19,20,21,22,23],your:[],your_usernam:8,yourself:[6,7,18],zero:[6,19],zip:[6,12],zone:7,zoneddatetim:7},titles:["Building the documentation","Code style guide","Consensus model","Contract catalogue","Interest Rate Swaps","Creating a Cordapp","Data model","Event scheduling","Getting set up","Welcome to the Corda repository!","What’s included?","Networking and messaging","Node administration","Writing oracle services","Protocol state machines","Release notes","Release process","Running the demos","Data types","Writing a contract","Writing a contract using clauses","Writing a contract test","Using the visualiser","Where to start"],titleterms:{"class":[19,20],"function":[14,19],about:8,administr:12,adopt:6,amount:18,api:19,app:5,approach:13,assert:[1,13],asset:19,attach:12,base:[],basic:13,bitcoin:6,build:0,buyer:14,cash:[3,18],catalogu:3,chain:21,chang:2,check:19,claus:[19,20],code:[1,19],command:19,comment:1,commerci:[3,19,20],commod:3,comparison:6,compil:1,complain:8,con:6,consensu:2,construct:19,continu:13,contract:[3,19,20,21],corda:9,cordapp:5,creat:[4,5],cryptographi:18,cut:16,data:[6,13,18],date:18,debug:20,demo:[17,23],detail:4,document:0,download:12,error:1,ethereum:6,event:7,exampl:7,featur:14,fix:12,framework:[],fungibleasset:18,futur:14,gener:[1,19],get:8,group:[19,20],guid:1,happen:19,how:[7,19],implement:[7,14],includ:10,instal:5,instanc:4,intellij:8,interest:[3,4,12],interfac:[],introduct:[7,13,14],known:[],kotlin:10,lack:8,length:1,lifecycl:[4,18],line:1,machin:14,make:19,manag:[],map:11,math:18,memori:[],messag:11,method:[],mileston:15,model:[2,6],monitor:12,multi:19,multipl:2,name:1,namedbyhash:18,network:11,node:[5,12],non:19,notari:2,note:15,oblig:3,obtain:2,occasion:[],oracl:13,orient:19,overview:6,pai:13,paper:[3,19,20],parti:[14,18,19],particular:19,per:13,plai:13,platform:[],plugin:5,pro:6,process:16,progress:14,properti:1,protocol:14,publickei:18,publicli:[],put:19,rate:[3,4,12],rational:6,releas:[15,16],repositori:9,requir:[0,19],run:[2,17],schedul:7,sdk:8,seller:14,servic:[2,5,11,13],set:8,signatur:2,singl:21,smart:19,space:1,start:[5,14,19,23],state:[14,18,19],step:16,style:[1,6],subprotocol:14,summari:20,support:18,suspend:14,swap:[3,4],technic:4,test:[14,19,21],theori:14,thing:19,thread:1,time:19,timestamp:2,track:14,trade:14,tradeoff:6,trader:[17,23],transact:[18,19,21],transmit:19,two:[13,14],type:[11,18],uniqueidentifi:18,unit:14,unreleas:[],upload:12,utxo:6,valid:2,vari:13,verifi:19,version:14,visualis:22,warn:1,web:17,welcom:9,what:10,where:[19,23],without:8,write:[13,19,20,21],your:[5,12,14,19]}}) \ 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 98582a2338..c1531e4fcb 100644 --- a/docs/build/html/transaction-data-types.html +++ b/docs/build/html/transaction-data-types.html @@ -93,20 +93,23 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -173,57 +176,78 @@

    Data types

    -

    There is a large library of data types used in Corda transactions and contract state objects.

    +

    Corda provides a large standard library of data types used in financial transactions and contract state objects. +These provide a common language for states and contracts.

    Amount

    -

    The Amount class is used to represent an amount of some fungible asset. It is a generic class which wraps around -a type used to define the underlying product, generally represented by an Issued instance, or this can be a more -complex type such as an obligation contract issuance definition (which in turn contains a token definition for whatever -the obligation is to be settled in).

    +

    The Amount class is used to represent an amount of some +fungible asset. It is a generic class which wraps around a type used to define the underlying product, called +the token. For instance it can be the standard JDK type Currency, or an Issued instance, or this can be +a more complex type such as an obligation contract issuance definition (which in turn contains a token definition +for whatever the obligation is to be settled in).

    Note

    Fungible is used here to mean that instances of an asset is interchangeable for any other identical instance, and that they can be split/merged. For example a £5 note can reasonably be exchanged for any other £5 note, and a £10 note can be exchanged for two £5 notes, or vice-versa.

    -

    Where a contract refers directly to an amount of something, Amount should wrap Issued, which in -turn can refer to a Currency (GBP, USD, CHF, etc.), or any other class. Future work in this area will include -introducing classes to represent non-currency things (such as commodities) that Issued can wrap. For more -complex amounts, Amount can wrap other types, for example to represent a number of Obligation contracts to be -delivered (themselves referring to a currency), an Amount such as the following would used:

    +

    Here are some examples:

    -
    Amount<Obligation.State<Currency>>
    +
    // A quantity of some specific currency like pounds, euros, dollars etc.
    +Amount<Currency>
    +// A quantity of currency that is issued by a specific issuer, for instance central bank vs other bank dollars
    +Amount<Issued<Currency>>
    +// A quantity of obligations to deliver currency of any issuer.
    +Amount<Obligation.State<Currency>>
     
    +

    Amount represents quantities as integers. For currencies the quantity represents pennies, cents or whatever +else the smallest integer amount for that currency is. You cannot use Amount to represent negative quantities +or fractional quantities: if you wish to do this then you must use a different type e.g. BigDecimal. Amount +defines methods to do addition and subtraction and these methods verify that the tokens on both sides of the operator +are equal (these are operator overloads in Kotlin and can be used as regular methods from Java). There are also +methods to do multiplication and division by integer amounts.

    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 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:

    +the details of a specific deal or asset (see Data model for further detail). In relational database terms +a state is like a row in a database. A reference to a state in the ledger (whether it has been consumed or not) +is represented with a StateRef object. If the state ref has been looked up from storage, you will have a +StateAndRef which is simply a StateRef plus the data.

    +

    The ContractState type is an interface that all states must implement. A TransactionState is a simple +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 common kinds +of state:

    OwnableState
    -
    A state which has an owner (represented as a PublicKey, discussed later). Exposes the owner and a function for -replacing the owner.
    +
    A state which has an owner (represented as a PublicKey, discussed later). Exposes the owner and a function +for replacing the owner e.g. when an asset is sold.
    LinearState
    -
    A state which links back to its previous state, creating a thread of states over time. Intended to simplify tracking -state versions.
    +
    A state which links back to its previous state, creating a thread of states over time. A linear state is +useful when modelling an indivisible/non-fungible thing like a specific deal, or an asset that can’t be +split (like a rare piece of art).
    DealState
    -
    A state representing an agreement between two or more parties. Intended to simplify implementing generic protocols -that manipulate many agreement types.
    +
    A LinearState representing an agreement between two or more parties. Intended to simplify implementing generic +protocols that manipulate many agreement types.
    FixableDealState
    A deal state, with further functions exposed to support fixing of interest rates.
    -

    Things (such as attachments) which are identified by their hash should implement the NamedByHash interface, -which standardises how the ID is extracted.

    +
    +
    +

    NamedByHash and UniqueIdentifier

    +

    Things which are identified by their hash, like transactions and attachments, should implement the NamedByHash +interface which standardises how the ID is extracted. Note that a hash is not a globally unique identifier: it +is always a derivative summary of the contents of the underlying data. Sometimes this isn’t what you want: +two deals that have exactly the same parameters and which are made simultaneously but which are logically different +can’t be identified by hash because their contents would be identical. Instead you would use UniqueIdentifier. +This is a combination of a (Java) UUID representing a globally unique 128 bit random number, and an arbitrary +string which can be paired with it. For instance the string may represent an existing “weak” (not guaranteed unique) +identifier for convenience purposes.

    FungibleAssets and Cash

    @@ -240,6 +264,11 @@ in place of the attachments themselves (see also LedgerTransaction
    , which involves verifying the signatures and associating them to the relevant command(s), and resolving the attachment references to the attachments. Commands with valid signatures are encapsulated in the AuthenticatedObject type.

    +
    +

    Note

    +

    A LedgerTransaction has not necessarily had its contracts be run, and thus could be contract-invalid +(but not signature-invalid). You can use the verify method as shown below to run the contracts.

    +

    When constructing a new transaction from scratch, you use TransactionBuilder, which is a mutable transaction that can be signed once modification of the internals is complete. It is typical for contract classes to expose helper methods that can contribute to a TransactionBuilder.

    @@ -264,13 +293,19 @@ write your tests using the

    Party and PublicKey

    -

    Identities of parties involved in signing a transaction can be represented simply by their PublicKey, or by further -information (such as name) using the Party class. An AuthenticatedObject contains a list of the public keys -for signatures present on the transaction, as well as list of parties for those public keys (where known).

    +

    Entities using the network are called parties. Parties can sign structures using keys, and a party may have many +keys under their control.

    +

    Parties may sometimes be identified pseudonomously, for example, in a transaction sent to your node as part of a +chain of custody it is important you can convince yourself of the transaction’s validity, but equally important that +you don’t learn anything about who was involved in that transaction. In these cases a public key may be present +without any identifying information about who owns it.

    +

    Identities of parties involved in signing a transaction can be represented simply by a PublicKey, or by further +information (such as name) using the Party class. An AuthenticatedObject represents an object (like a command) +that has been signed by a set of parties.

    Note

    -

    These types are provisional and are likely to change in future, for example to add additional information to -Party.

    +

    These types are provisional and will change significantly in future as the identity framework becomes more +fleshed out.

    @@ -286,6 +321,13 @@ bank holidays). The BusinessCal from files on disk, but in future this is likely to involve reference data oracles in order to ensure consensus on the dates used.

    +
    +

    Cryptography & maths support

    +

    The SecureHash class represents a secure hash of unknown algorithm. We currently define only a single subclass, +SecureHash.SHA256. There are utility methods to create them, parse them and so on.

    +

    We also provide some mathematical utilities, in particular a set of interpolators and classes for working with +splines. These can be found in the maths package.

    +
    diff --git a/docs/build/html/tutorial-contract-clauses.html b/docs/build/html/tutorial-contract-clauses.html index 8fdce73c88..b4aa78084d 100644 --- a/docs/build/html/tutorial-contract-clauses.html +++ b/docs/build/html/tutorial-contract-clauses.html @@ -93,12 +93,13 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    @@ -110,6 +111,7 @@
  • Clauses
  • Group Clause
  • Summary
  • +
  • Debugging
  • Writing a contract test
  • @@ -174,13 +176,16 @@

    Writing a contract using clauses

    This tutorial will take you through restructuring the commercial paper contract to use clauses. You should have already completed “Writing a contract”.

    -

    Clauses are essentially micro-contracts which contain independent verification logic, and are composed together to form -a contract. With appropriate design, they can be made to be reusable, for example issuing contract state objects is -generally the same for all fungible contracts, so a single issuance clause can be shared. This cuts down on scope for -error, and improves consistency of behaviour.

    -

    Clauses can be composed of subclauses, either to combine clauses in different ways, or to apply specialised clauses. -In the case of commercial paper, we have a Group outermost clause, which will contain the Issue, Move and -Redeem clauses. The result is a contract that looks something like this:

    +

    Clauses are essentially micro-contracts which contain independent verification logic, and can be logically composed +together to form a contract. Clauses are designed to enable re-use of common logic, for example issuing state objects +is generally the same for all fungible contracts, so a common issuance clause can be inherited for each contract’s +issue clause. This cuts down on scope for error, and improves consistency of behaviour. By splitting verification logic +into smaller chunks, they can also be readily tested in isolation.

    +

    Clauses can be composed of subclauses, for example the AllClause or AnyClause clauses take list of clauses +that they delegate to. Clauses can also change the scope of states and commands being verified, for example grouping +together fungible state objects and running a clause against each distinct group.

    +

    The commercial paper contract has a Group outermost clause, which contains the Issue, Move and Redeem +clauses. The result is a contract that looks something like this:

    1. @@ -197,19 +202,17 @@ In the case of commercial paper, we have a

    Commercial paper class

    -

    To use the clause verification logic, the contract needs to call the verifyClauses() function, passing in the transaction, -a list of clauses to verify, and a collection of commands the clauses are expected to handle all of. This list of -commands is important because verifyClauses() checks that none of the commands are left unprocessed at the end, and -raises an error if they are. The following examples are trimmed to the modified class definition and added elements, for -brevity:

    +

    To use the clause verification logic, the contract needs to call the verifyClause function, passing in the +transaction, a clause to verify, and a collection of commands the clauses are expected to handle all of. This list of +commands is important because verifyClause checks that none of the commands are left unprocessed at the end, and +raises an error if they are. The top level clause would normally be a composite clause (such as AnyComposition, +AllComposition, etc.) which contains further clauses. The following examples are trimmed to the modified class +definition and added elements, for brevity:

    class CommercialPaper : Contract {
         override val legalContractReference: SecureHash = SecureHash.sha256("https://en.wikipedia.org/wiki/Commercial_paper")
     
    -    private fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<CommandData>>
    -        = tx.commands.select<Commands>()
    -
    -    override fun verify(tx: TransactionForContract) = verifyClauses(tx, listOf(Clauses.Group()), extractCommands(tx))
    +    override fun verify(tx: TransactionForContract) = verifyClause(tx, Clauses.Group(), tx.commands.select<Commands>())
     
    public class CommercialPaper implements Contract {
    @@ -218,17 +221,9 @@ brevity:

    return SecureHash.Companion.sha256("https://en.wikipedia.org/wiki/Commercial_paper"); } - @Override - public Collection<AuthenticatedObject<CommandData>> extractCommands(@NotNull TransactionForContract tx) { - return tx.getCommands() - .stream() - .filter((AuthenticatedObject<CommandData> command) -> { return command.getValue() instanceof Commands; }) - .collect(Collectors.toList()); - } - @Override public void verify(@NotNull TransactionForContract tx) throws IllegalArgumentException { - ClauseVerifier.verifyClauses(tx, Collections.singletonList(new Clause.Group()), extractCommands(tx)); + ClauseVerifier.verifyClause(tx, new Clauses.Group(), extractCommands(tx)); }
    @@ -237,30 +232,25 @@ brevity:

    Clauses

    We’ll tackle the inner clauses that contain the bulk of the verification logic, first, and the clause which handles -grouping of input/output states later. The inner clauses need to implement the GroupClause interface, which defines -the verify() function, and properties (ifMatched, ifNotMatched and requiredCommands) defining how the clause -is processed. These properties specify the command(s) which must be present in order for the clause to be matched, -and what to do after processing the clause depending on whether it was matched or not.

    -

    The verify() functions defined in the SingleClause and GroupClause interfaces is similar to the conventional -Contract verification function, although it adds new parameters and returns the set of commands which it has processed. -Normally this returned set is identical to the commands matched in order to trigger the clause, however in some cases the -clause may process optional commands which it needs to report that it has handled, or may by designed to only process -the first (or otherwise) matched command.

    -

    The Move clause for the commercial paper contract is relatively simple, so lets start there:

    +grouping of input/output states later. The clauses must implement the Clause interface, which defines +the verify function, and the requiredCommands property used to determine the conditions under which a clause +is triggered. Normally clauses would extend ConcreteClause which provides defaults suitable for a clause which +verifies transactions, rather than delegating to other clauses.

    +

    The verify function defined in the Clause interface is similar to the conventional Contract verification +function, although it adds new parameters and returns the set of commands which it has processed. Normally this returned +set is identical to the requiredCommands used to trigger the clause, however in some cases the clause may process +further optional commands which it needs to report that it has handled.

    +

    The Move clause for the commercial paper contract is relatively simple, so we will start there:

    -
    class Move: GroupClause<State, Issued<Terms>> {
    -    override val ifNotMatched: MatchBehaviour
    -        get() = MatchBehaviour.CONTINUE
    -    override val ifMatched: MatchBehaviour
    -        get() = MatchBehaviour.END
    +
    class Move: ConcreteClause<State, Commands, Issued<Terms>>() {
         override val requiredCommands: Set<Class<out CommandData>>
             get() = setOf(Commands.Move::class.java)
     
         override fun verify(tx: TransactionForContract,
                             inputs: List<State>,
                             outputs: List<State>,
    -                        commands: Collection<AuthenticatedObject<CommandData>>,
    -                        token: Issued<Terms>): Set<CommandData> {
    +                        commands: List<AuthenticatedObject<Commands>>,
    +                        groupingKey: Issued<Terms>?): Set<Commands> {
             val command = commands.requireSingleCommand<Commands.Move>()
             val input = inputs.single()
             requireThat {
    @@ -274,37 +264,31 @@ the first (or otherwise) matched command.

    }
    -
    public class Move implements GroupClause<State, State> {
    -    @Override
    -    public MatchBehaviour getIfNotMatched() {
    -        return MatchBehaviour.CONTINUE;
    -    }
    -
    -    @Override
    -    public MatchBehaviour getIfMatched() {
    -        return MatchBehaviour.END;
    -    }
    -
    +
    class Move extends ConcreteClause<State, Commands, State> {
    +    @NotNull
         @Override
         public Set<Class<? extends CommandData>> getRequiredCommands() {
             return Collections.singleton(Commands.Move.class);
         }
     
    +    @NotNull
         @Override
    -    public Set<CommandData> verify(@NotNull TransactionForContract tx,
    +    public Set<Commands> verify(@NotNull TransactionForContract tx,
                                        @NotNull List<? extends State> inputs,
                                        @NotNull List<? extends State> outputs,
    -                                   @NotNull Collection<? extends AuthenticatedObject<? extends CommandData>> commands,
    -                                   @NotNull State token) {
    -        AuthenticatedObject<CommandData> cmd = requireSingleCommand(tx.getCommands(), JavaCommercialPaper.Commands.Move.class);
    +                                   @NotNull List<? extends AuthenticatedObject<? extends Commands>> commands,
    +                                   @NotNull State groupingKey) {
    +        AuthenticatedObject<Commands.Move> cmd = requireSingleCommand(tx.getCommands(), Commands.Move.class);
             // There should be only a single input due to aggregation above
             State input = single(inputs);
     
    -        requireThat(require -> {
    -            require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner()));
    -            require.by("the state is propagated", outputs.size() == 1);
    -            return Unit.INSTANCE;
    -        });
    +        if (!cmd.getSigners().contains(input.getOwner()))
    +            throw new IllegalStateException("Failed requirement: the transaction is signed by the owner of the CP");
    +
    +        // Check the output CP state is the same as the input state, ignoring the owner field.
    +        if (outputs.size() != 1) {
    +            throw new IllegalStateException("the state is propagated");
    +        }
             // Don't need to check anything else, as if outputs.size == 1 then the output is equal to
             // the input ignoring the owner field due to the grouping.
             return Collections.singleton(cmd.getValue());
    @@ -313,100 +297,44 @@ the first (or otherwise) matched command.

    -
    -
    The post-processing MatchBehaviour options are:
    -
      -
    • CONTINUE
    • -
    • END
    • -
    • ERROR
    • -
    -
    -
    -

    In this case we process commands against each group, until the first matching clause is found, so we END on a match -and CONTINUE otherwise. ERROR can be used as a part of a clause which must always/never be matched. By default -clauses are always matched (requiredCommands is an empty set), execution continues after a clause is matched, and an -error is raised if a clause is not matched.

    Group Clause

    We need to wrap the move clause (as well as the issue and redeem clauses - see the relevant contract code for their -full specifications) in an outer clause. For this we extend the standard GroupClauseVerifier and specify how to -group input/output states, as well as the clauses to run on each group.

    +full specifications) in an outer clause that understands how to group contract states and objects. For this we extend +the standard GroupClauseVerifier and specify how to group input/output states, as well as the top-level to run on +each group. As with the top level clause on a contract, this is normally a composite clause that delegates to subclauses.

    -
    class Group : GroupClauseVerifier<State, Issued<Terms>>() {
    -    override val ifNotMatched: MatchBehaviour
    -        get() = MatchBehaviour.ERROR
    -    override val ifMatched: MatchBehaviour
    -        get() = MatchBehaviour.END
    -    override val clauses: List<GroupClause<State, Issued<Terms>>>
    -        get() = listOf(
    -                Clause.Redeem(),
    -                Clause.Move(),
    -                Clause.Issue()
    -        )
    -
    -    override fun extractGroups(tx: TransactionForContract): List<TransactionForContract.InOutGroup<State, Issued<Terms>>>
    +
    class Group : GroupClauseVerifier<State, Commands, Issued<Terms>>(
    +    AnyComposition(
    +        Redeem(),
    +        Move(),
    +        Issue())) {
    +    override fun groupStates(tx: TransactionForContract): List<TransactionForContract.InOutGroup<State, Issued<Terms>>>
                 = tx.groupStates<State, Issued<Terms>> { it.token }
     }
     
    -
    public class Group extends GroupClauseVerifier<State, State> {
    -    @Override
    -    public MatchBehaviour getIfMatched() {
    -        return MatchBehaviour.END;
    +
    class Group extends GroupClauseVerifier<State, Commands, State> {
    +    public Group() {
    +        super(new AnyComposition<>(
    +            new Clauses.Redeem(),
    +            new Clauses.Move(),
    +            new Clauses.Issue()
    +        ));
         }
     
    +    @NotNull
         @Override
    -    public MatchBehaviour getIfNotMatched() {
    -        return MatchBehaviour.ERROR;
    -    }
    -
    -    @Override
    -    public List<com.r3corda.core.contracts.clauses.GroupClause<State, State>> getClauses() {
    -        final List<GroupClause<State, State>> clauses = new ArrayList<>();
    -
    -        clauses.add(new Clause.Redeem());
    -        clauses.add(new Clause.Move());
    -        clauses.add(new Clause.Issue());
    -
    -        return clauses;
    -    }
    -
    -    @Override
    -    public List<InOutGroup<State, State>> extractGroups(@NotNull TransactionForContract tx) {
    +    public List<InOutGroup<State, State>> groupStates(@NotNull TransactionForContract tx) {
             return tx.groupStates(State.class, State::withoutOwner);
         }
     }
     
    -

    We then pass this clause into the outer ClauseVerifier contract by returning it from the clauses property. We -also implement the extractCommands() function, which filters commands on the transaction down to the set the -contained clauses must handle (any unmatched commands at the end of clause verification results in an exception to be -thrown).

    -
    -
    override val clauses: List<SingleClause>
    -    get() = listOf(Clauses.Group())
    -
    -override fun extractCommands(tx: TransactionForContract): List<AuthenticatedObject<CommandData>>
    -    = tx.commands.select<Commands>()
    -
    -
    -
    @Override
    -public List<SingleClause> getClauses() {
    -    return Collections.singletonList(new Clause.Group());
    -}
    -
    -@Override
    -public Collection<AuthenticatedObject<CommandData>> extractCommands(@NotNull TransactionForContract tx) {
    -    return tx.getCommands()
    -            .stream()
    -            .filter((AuthenticatedObject<CommandData> command) -> { return command.getValue() instanceof Commands; })
    -            .collect(Collectors.toList());
    -}
    -
    -
    -
    +

    For the CommercialPaper contract, this is the top level clause for the contract, and is passed directly into +verifyClause (see the example code at the top of this tutorial).

    Summary

    @@ -415,6 +343,13 @@ thrown).

    (Redeem, Move and Issue). This reflects the flow of verification: In order to verify a CommercialPaper we first group states, check which commands are specified, and run command-specific verification logic accordingly.

    +
    +

    Debugging

    +

    Debugging clauses which have been composed together can be complicated due to the difficulty in knowing which clauses +have been matched, whether specific clauses failed to match or passed verification, etc. There is “trace” level +logging code in the clause verifier which evaluates which clauses will be matched and logs them, before actually +performing the validation. To enable this, ensure trace level logging is enabled on the Clause interface.

    +
    diff --git a/docs/build/html/tutorial-contract.html b/docs/build/html/tutorial-contract.html index cafd38b5a0..87e783a744 100644 --- a/docs/build/html/tutorial-contract.html +++ b/docs/build/html/tutorial-contract.html @@ -93,18 +93,20 @@
  • Data types
  • Consensus model
  • Networking and messaging
  • +
  • Creating a Cordapp
  • Running the demos
  • Node administration
  • Contracts

    Tutorials

    • Where to start
    • Writing a contract
    • @@ -180,15 +184,22 @@

      Writing a contract

      This tutorial will take you through how the commercial paper contract works. This uses a simple contract structure of everything being in one contract class, while most actual contracts in Corda are broken into clauses (which we’ll -discuss in the next tutorial). You can see the full Kotlin version of this contract in the code as CommercialPaperLegacy.

      -

      The code in this tutorial is available in both Kotlin and Java. You can quickly switch between them to get a feeling -for how Kotlin syntax works.

      +discuss in the next tutorial). Clauses help reduce tedious boilerplate, but it’s worth understanding how a +contract is built without them before starting.

      +

      You can see the full Kotlin version of this contract in the code as CommercialPaperLegacy. The code in this +tutorial is available in both Kotlin and Java. You can quickly switch between them to get a feeling for how +Kotlin syntax works.

      +
      +

      Where to put your code

      +

      A CorDapp is a collection of contracts, state definitions, protocols and other ways to extend the server. To create +one you would just create a Java-style project as normal, with your choice of build system (Maven, Gradle, etc). +Then add a dependency on com.r3corda:core:0.X where X is the milestone number you are depending on. The core +module defines the base classes used in this tutorial.

      +

      Starting the commercial paper class

      A smart contract is a class that implements the Contract interface. This can be either implemented directly, or -via an abstract contract such as ClauseVerifier. For now, contracts have to be a part of the main codebase, as -dynamic loading of contract code is not yet implemented. Therefore, we start by creating a file named either -CommercialPaper.kt or CommercialPaper.java in the contracts/src/main directory with the following contents:

      +by subclassing an abstract contract such as OnLedgerAsset.

      class CommercialPaper : Contract {
           override val legalContractReference: SecureHash = SecureHash.sha256("https://en.wikipedia.org/wiki/Commercial_paper");
      @@ -216,11 +227,12 @@ dynamic loading of contract code is not yet implemented. Therefore, we start by
       

      Every contract must have at least a getLegalContractReference() and a verify() method. In Kotlin we express a getter without a setter as an immutable property (val). The legal contract reference is supposed to be a hash of a document that describes the legal contract and may take precedence over the code, in case of a dispute.

      +
      +

      Note

      +

      The way legal contract prose is bound to a smart contract implementation will change in future.

      +

      The verify method returns nothing. This is intentional: the function either completes correctly, or throws an exception, in which case the transaction is rejected.

      -

      We also need to define a constant hash that would, in a real system, be the hash of the program bytecode. For now -we just set it to a dummy value as dynamic loading and sandboxing of bytecode is not implemented. This constant -isn’t shown in the code snippet but is called CP_PROGRAM_ID.

      So far, so simple. Now we need to define the commercial paper state, which represents the fact of ownership of a piece of issued paper.

      @@ -229,100 +241,115 @@ piece of issued paper.

      A state is a class that stores data that is checked by the contract.

      data class State(
      -  val issuance: InstitutionReference,
      -  val owner: PublicKey,
      -  val faceValue: Amount,
      -  val maturityDate: Instant
      -) : ContractState {
      -  override val programRef = CP_PROGRAM_ID
      +        val issuance: PartyAndReference,
      +        override val owner: PublicKey,
      +        val faceValue: Amount<Issued<Currency>>,
      +        val maturityDate: Instant
      +) : OwnableState {
      +    override val contract = CommercialPaper()
      +    override val participants = listOf(owner)
       
      -  fun withoutOwner() = copy(owner = NullPublicKey)
      +    fun withoutOwner() = copy(owner = NullPublicKey)
      +    override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
       }
       
      -
      public static class State implements ContractState, SerializeableWithKryo {
      -  private InstitutionReference issuance;
      -  private PublicKey owner;
      -  private Amount faceValue;
      -  private Instant maturityDate;
      +
      public static class State implements OwnableState {
      +    private PartyAndReference issuance;
      +    private PublicKey owner;
      +    private Amount<Issued<Currency>> faceValue;
      +    private Instant maturityDate;
       
      -  public State() {}  // For serialization
      +    public State() {
      +    }  // For serialization
       
      -  public State(InstitutionReference issuance, PublicKey owner, Amount faceValue, Instant maturityDate) {
      -      this.issuance = issuance;
      -      this.owner = owner;
      -      this.faceValue = faceValue;
      -      this.maturityDate = maturityDate;
      -  }
      +    public State(PartyAndReference issuance, PublicKey owner, Amount<Issued<Currency>> faceValue,
      +                 Instant maturityDate) {
      +        this.issuance = issuance;
      +        this.owner = owner;
      +        this.faceValue = faceValue;
      +        this.maturityDate = maturityDate;
      +    }
       
      -  public InstitutionReference getIssuance() {
      -      return issuance;
      -  }
      +    public State copy() {
      +        return new State(this.issuance, this.owner, this.faceValue, this.maturityDate);
      +    }
       
      -  public PublicKey getOwner() {
      -      return owner;
      -  }
      +    @NotNull
      +    @Override
      +    public Pair<CommandData, OwnableState> withNewOwner(@NotNull PublicKey newOwner) {
      +        return new Pair<>(new Commands.Move(), new State(this.issuance, newOwner, this.faceValue, this.maturityDate));
      +    }
       
      -  public Amount getFaceValue() {
      -      return faceValue;
      -  }
      +    public PartyAndReference getIssuance() {
      +        return issuance;
      +    }
       
      -  public Instant getMaturityDate() {
      -      return maturityDate;
      -  }
      +    public PublicKey getOwner() {
      +        return owner;
      +    }
       
      -  @NotNull
      -  @Override
      -  public SecureHash getProgramRef() {
      -      return SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)");
      -  }
      +    public Amount<Issued<Currency>> getFaceValue() {
      +        return faceValue;
      +    }
       
      -  @Override
      -  public boolean equals(Object o) {
      -      if (this == o) return true;
      -      if (o == null || getClass() != o.getClass()) return false;
      +    public Instant getMaturityDate() {
      +        return maturityDate;
      +    }
       
      -      State state = (State) o;
      +    @NotNull
      +    @Override
      +    public Contract getContract() {
      +        return new JavaCommercialPaper();
      +    }
       
      -      if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false;
      -      if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false;
      -      if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false;
      -      return !(maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null);
      +    @Override
      +    public boolean equals(Object o) {
      +        if (this == o) return true;
      +        if (o == null || getClass() != o.getClass()) return false;
       
      -  }
      +        State state = (State) o;
       
      -  @Override
      -  public int hashCode() {
      -      int result = issuance != null ? issuance.hashCode() : 0;
      -      result = 31 * result + (owner != null ? owner.hashCode() : 0);
      -      result = 31 * result + (faceValue != null ? faceValue.hashCode() : 0);
      -      result = 31 * result + (maturityDate != null ? maturityDate.hashCode() : 0);
      -      return result;
      -  }
      +        if (issuance != null ? !issuance.equals(state.issuance) : state.issuance != null) return false;
      +        if (owner != null ? !owner.equals(state.owner) : state.owner != null) return false;
      +        if (faceValue != null ? !faceValue.equals(state.faceValue) : state.faceValue != null) return false;
      +        return !(maturityDate != null ? !maturityDate.equals(state.maturityDate) : state.maturityDate != null);
      +    }
       
      -  public State withoutOwner() {
      -      return new State(issuance, NullPublicKey.INSTANCE, faceValue, maturityDate);
      -  }
      +    @Override
      +    public int hashCode() {
      +        int result = issuance != null ? issuance.hashCode() : 0;
      +        result = 31 * result + (owner != null ? owner.hashCode() : 0);
      +        result = 31 * result + (faceValue != null ? faceValue.hashCode() : 0);
      +        result = 31 * result + (maturityDate != null ? maturityDate.hashCode() : 0);
      +        return result;
      +    }
      +
      +    @NotNull
      +    @Override
      +    public List<PublicKey> getParticipants() {
      +        return ImmutableList.of(this.owner);
      +    }
       }
       
      -

      We define a class that implements the ContractState and SerializableWithKryo interfaces. The -latter is an artifact of how the prototype implements serialization and can be ignored for now: it wouldn’t work -like this in any final product.

      -

      The ContractState interface requires us to provide a getProgramRef method that is supposed to return a hash of -the bytecode of the contract itself. For now this is a dummy value and isn’t used: later on, this mechanism will change. -Beyond that it’s a freeform object into which we can put anything which can be serialized.

      +

      We define a class that implements the ContractState interface.

      +

      The ContractState interface requires us to provide a getContract method that returns an instance of the +contract class itself. In future, this will change to support dynamic loading of contracts with versioning +and signing constraints, but for now this is how it’s written.

      We have four fields in our state:

        -
      • issuance: a reference to a specific piece of commercial paper at a party
      • -
      • owner: the public key of the current owner. This is the same concept as seen in Bitcoin: the public key has no +
      • issuance, a reference to a specific piece of commercial paper issued by some party.
      • +
      • owner, the public key of the current owner. This is the same concept as seen in Bitcoin: the public key has no attached identity and is expected to be one-time-use for privacy reasons. However, unlike in Bitcoin, we model -ownership at the level of individual contracts rather than as a platform-level concept as we envisage many +ownership at the level of individual states rather than as a platform-level concept as we envisage many (possibly most) contracts on the platform will not represent “owner/issuer” relationships, but “party/party” relationships such as a derivative contract.
      • -
      • faceValue: an Amount, which wraps an integer number of pennies and a currency.
      • -
      • maturityDate: an Instant, which is a type +
      • faceValue, an Amount<Issued<Currency>>, which wraps an integer number of pennies and a currency that is +specific to some issuer (e.g. a regular bank, a central bank, etc). You can read more about this very common +type in Data types.
      • +
      • maturityDate, an Instant, which is a type from the Java 8 standard time library. It defines a point on the timeline.

      States are immutable, and thus the class is defined as immutable as well. The data modifier in the Kotlin version @@ -330,22 +357,23 @@ causes the compiler to generate the equals/hashCode/toString methods automatical be used to create variants of the original object. Data classes are similar to case classes in Scala, if you are familiar with that language. The withoutOwner method uses the auto-generated copy method to return a version of the state with the owner public key blanked out: this will prove useful later.

      -

      The Java code compiles to the same bytecode as the Kotlin version, but as you can see, is much more verbose.

      +

      The Java code compiles to almost identical bytecode as the Kotlin version, but as you can see, is much more verbose.

      Commands

      The logic for a contract may vary depending on what stage of a lifecycle it is automating. So it can be useful to pass additional data into the contract code that isn’t represented by the states which exist permanently in the ledger.

      -

      For this purpose we have commands. Often, they don’t need to contain any data at all, they just need to exist. A command +

      For this purpose we have commands. Often they don’t need to contain any data at all, they just need to exist. A command is a piece of data associated with some signatures. By the time the contract runs the signatures have already been checked, so from the contract code’s perspective, a command is simply a data structure with a list of attached -public keys. Each key had a signature proving that the corresponding private key was used to sign.

      +public keys. Each key had a signature proving that the corresponding private key was used to sign. Because of this +approach contracts never actually interact or work with digital signatures directly.

      Let’s define a few commands now:

      -
      interface Commands : Command {
      -    object Move : Commands
      -    object Redeem : Commands
      -    object Issue : Commands
      +
      interface Commands : CommandData {
      +    class Move : TypeOnlyCommandData(), Commands
      +    class Redeem : TypeOnlyCommandData(), Commands
      +    class Issue : TypeOnlyCommandData(), Commands
       }
       
      @@ -374,9 +402,10 @@ public keys. Each key had a signature proving that the corresponding private key
      -

      The object keyword in Kotlin just defines a singleton object. As the commands don’t need any additional data in our -case, they can be empty and we just use their type as the important information. Java has no syntax for declaring -singletons, so we just define a class that considers any other instance to be equal and that’s good enough.

      +

      We define a simple grouping interface or static class, this gives us a type that all our commands have in common, +then we go ahead and create three commands: Move, Redeem, Issue. TypeOnlyCommandData is a helpful utility +for the case when there’s no data inside the command; only the existence matters. It defines equals and hashCode +such that any instances always compare equal and hash to the same value.

      The verify function

      @@ -388,14 +417,17 @@ by taking the code references inside each state. Each contract is run only once. 2 cash states and 1 commercial paper state as input, and has as output 1 cash state and 1 commercial paper state, will run two contracts one time each: Cash and CommercialPaper.

      -
      override fun verify(tx: TransactionForVerification) {
      +
      override fun verify(tx: TransactionForContract) {
           // Group by everything except owner: any modification to the CP at all is considered changing it fundamentally.
      -    val groups = tx.groupStates() { it: State -> it.withoutOwner() }
      +    val groups = tx.groupStates(State::withoutOwner)
      +
      +    // There are two possible things that can be done with this CP. The first is trading it. The second is redeeming
      +    // it for cash on or after the maturity date.
           val command = tx.commands.requireSingleCommand<CommercialPaper.Commands>()
       
      @Override
      -public void verify(@NotNull TransactionForVerification tx) {
      +public void verify(TransactionForContract tx) {
           List<InOutGroup<State, State>> groups = tx.groupStates(State.class, State::withoutOwner);
           AuthenticatedObject<Command> cmd = requireSingleCommand(tx.getCommands(), Commands.class);
       
      @@ -403,9 +435,10 @@ run two contracts one time each: Cash and CommercialPaper.

      We start by using the groupStates method, which takes a type and a function. State grouping is a way of ensuring your contract can handle multiple unrelated states of the same type in the same transaction, which is needed for -splitting/merging of assets, atomic swaps and so on. The second line does what the code suggests: it searches for -a command object that inherits from the CommercialPaper.Commands supertype, and either returns it, or throws an -exception if there’s zero or more than one such command.

      +splitting/merging of assets, atomic swaps and so on. More on this next.

      +

      The second line does what the code suggests: it searches for a command object that inherits from the +CommercialPaper.Commands supertype, and either returns it, or throws an exception if there’s zero or more than one +such command.

      Using state groups

      @@ -434,11 +467,11 @@ that should be checked for validity together.

      inputs e.g. because she received the dollars in two payments. The input and output amounts do balance correctly, but the cash smart contract must consider the pounds and the dollars separately because they are not fungible: they cannot be merged together. So we have two groups: A and B.

      -

      The TransactionForVerification.groupStates method handles this logic for us: firstly, it selects only states of the +

      The TransactionForContract.groupStates method handles this logic for us: firstly, it selects only states of the given type (as the transaction may include other types of state, such as states representing bond ownership, or a multi-sig state) and then it takes a function that maps a state to a grouping key. All states that share the same key are grouped together. In the case of the cash example above, the grouping key would be the currency.

      -

      In other kinds of contract, we don’t want CP to be fungible: merging and splitting is (in our example) not allowed. +

      In this kind of contract we don’t want CP to be fungible: merging and splitting is (in our example) not allowed. So we just use a copy of the state minus the owner field as the grouping key.

      Here are some code examples:

      @@ -493,50 +526,52 @@ in equals and hashCode.

      After extracting the command and the groups, we then iterate over each group and verify it meets the required business logic.

      -
      val time = tx.time
      -for (group in groups) {
      +
      val timestamp: Timestamp? = tx.timestamp
      +
      +for ((inputs, outputs, key) in groups) {
           when (command.value) {
               is Commands.Move -> {
      -            val input = group.inputs.single()
      +            val input = inputs.single()
                   requireThat {
      -                "the transaction is signed by the owner of the CP" by (command.signers.contains(input.owner))
      +                "the transaction is signed by the owner of the CP" by (input.owner in command.signers)
                       "the state is propagated" by (group.outputs.size == 1)
      +                // Don't need to check anything else, as if outputs.size == 1 then the output is equal to
      +                // the input ignoring the owner field due to the grouping.
                   }
               }
       
               is Commands.Redeem -> {
      -            val input = group.inputs.single()
      -            val received = tx.outStates.sumCashBy(input.owner)
      -            if (time == null) throw IllegalArgumentException("Redemption transactions must be timestamped")
      +            // Redemption of the paper requires movement of on-ledger cash.
      +            val input = inputs.single()
      +            val received = tx.outputs.sumCashBy(input.owner)
      +            val time = timestamp?.after ?: throw IllegalArgumentException("Redemptions must be timestamped")
                   requireThat {
      -                "the paper must have matured" by (time > input.maturityDate)
      +                "the paper must have matured" by (time >= input.maturityDate)
                       "the received amount equals the face value" by (received == input.faceValue)
      -                "the paper must be destroyed" by group.outputs.isEmpty()
      -                "the transaction is signed by the owner of the CP" by (command.signers.contains(input.owner))
      +                "the paper must be destroyed" by outputs.isEmpty()
      +                "the transaction is signed by the owner of the CP" by (input.owner in command.signers)
                   }
               }
       
               is Commands.Issue -> {
      -            val output = group.outputs.single()
      -            if (time == null) throw IllegalArgumentException("Issuance transactions must be timestamped")
      +            val output = outputs.single()
      +            val time = timestamp?.before ?: throw IllegalArgumentException("Issuances must be timestamped")
                   requireThat {
                       // Don't allow people to issue commercial paper under other entities identities.
      -                "the issuance is signed by the claimed issuer of the paper" by
      -                        (command.signers.contains(output.issuance.party.owningKey))
      -                "the face value is not zero" by (output.faceValue.pennies > 0)
      -                "the maturity date is not in the past" by (time < output.maturityDate )
      +                "output states are issued by a command signer" by (output.issuance.party.owningKey in command.signers)
      +                "output values sum to more than the inputs" by (output.faceValue.quantity > 0)
      +                "the maturity date is not in the past" by (time < output.maturityDate)
                       // Don't allow an existing CP state to be replaced by this issuance.
      -                "there is no input state" by group.inputs.isEmpty()
      +                "can't reissue an existing state" by inputs.isEmpty()
                   }
               }
       
      -        // TODO: Think about how to evolve contracts over time with new commands.
               else -> throw IllegalArgumentException("Unrecognised command")
           }
       }
       
      -
      Instant time = tx.getTime();   // Can be null/missing.
      +
      Timestamp time = tx.getTimestamp();   // Can be null/missing.
       for (InOutGroup<State> group : groups) {
           List<State> inputs = group.getInputs();
           List<State> outputs = group.getOutputs();
      @@ -544,34 +579,20 @@ logic.

      // For now do not allow multiple pieces of CP to trade in a single transaction. Study this more! State input = single(filterIsInstance(inputs, State.class)); - requireThat(require -> { - require.by("the transaction is signed by the owner of the CP", cmd.getSigners().contains(input.getOwner())); - return Unit.INSTANCE; - }); + checkState(cmd.getSigners().contains(input.getOwner()), "the transaction is signed by the owner of the CP"); if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Move) { - requireThat(require -> { - require.by("the state is propagated", outputs.size() == 1); - return Unit.INSTANCE; - }); + checkState(outputs.size() == 1, "the state is propagated"); // Don't need to check anything else, as if outputs.size == 1 then the output is equal to // the input ignoring the owner field due to the grouping. } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Redeem) { - TimestampCommand timestampCommand = tx.getTimestampBy(((Commands.Redeem) cmd.getValue()).notary); - Instant time = null == timestampCommand - ? null - : timestampCommand.getBefore(); + checkNotNull(timem "must be timestamped"); + Instant t = time.getBefore(); Amount<Issued<Currency>> received = CashKt.sumCashBy(tx.getOutputs(), input.getOwner()); - requireThat(require -> { - require.by("must be timestamped", timestampCommand != null); - require.by("received amount equals the face value: " - + received + " vs " + input.getFaceValue(), received.equals(input.getFaceValue())); - require.by("the paper must have matured", time != null && !time.isBefore(input.getMaturityDate())); - require.by("the received amount equals the face value", input.getFaceValue().equals(received)); - require.by("the paper must be destroyed", outputs.isEmpty()); - return Unit.INSTANCE; - }); + checkState(received.equals(input.getFaceValue()), "received amount equals the face value"); + checkState(t.isBefore(input.getMaturityDate(), "the paper must have matured"); + checkState(outputs.isEmpty(), "the paper must be destroyed"); } else if (cmd.getValue() instanceof JavaCommercialPaper.Commands.Issue) { // .. etc .. (see Kotlin for full definition) } @@ -584,7 +605,11 @@ logic.

      may be missing here. We check for it being null later.

      Note

      -

      In the Kotlin version, as long as we write a comparison with the transaction time first, the compiler will +

      In future timestamping may be mandatory for all transactions.

      +
      +
      +

      Warning

      +

      In the Kotlin version as long as we write a comparison with the transaction time first the compiler will verify we didn’t forget to check if it’s missing. Unfortunately due to the need for smooth Java interop, this check won’t happen if we write e.g. someDate > time, it has to be time < someDate. So it’s good practice to always write the transaction timestamp first.

      @@ -593,18 +618,18 @@ always write the transaction timestamp first.

      this group. We do not allow multiple units of CP to be split or merged even if they are owned by the same owner. The single() method is a static extension method defined by the Kotlin standard library: given a list, it throws an exception if the list size is not 1, otherwise it returns the single item in that list. In Java, this appears as a -regular static method of the type familiar from many FooUtils type singleton classes. In Kotlin, it appears as a -method that can be called on any JDK list. The syntax is slightly different but behind the scenes, the code compiles -to the same bytecodes.

      +regular static method of the type familiar from many FooUtils type singleton classes and we have statically imported it +here. In Kotlin, it appears as a method that can be called on any JDK list. The syntax is slightly different but +behind the scenes, the code compiles to the same bytecodes.

      Next, we check that the transaction was signed by the public key that’s marked as the current owner of the commercial paper. Because the platform has already verified all the digital signatures before the contract begins execution, all we have to do is verify that the owner’s public key was one of the keys that signed the transaction. The Java code -is straightforward. The Kotlin version looks a little odd: we have a requireThat construct that looks like it’s +is straightforward: we are simply using the Preconditions.checkState method from Guava. The Kotlin version looks a little odd: we have a requireThat construct that looks like it’s built into the language. In fact requireThat is an ordinary function provided by the platform’s contract API. Kotlin supports the creation of domain specific languages through the intersection of several features of the language, and we use it here to support the natural listing of requirements. To see what it compiles down to, look at the Java version. Each "string" by (expression) statement inside a requireThat turns into an assertion that the given expression is -true, with an exception being thrown that contains the string if not. It’s just another way to write out a regular +true, with an IllegalStateException being thrown that contains the string if not. It’s just another way to write out a regular assertion, but with the English-language requirement being put front and center.

      Next, we take one of two paths, depending on what the type of the command object is.

      If the command is a Move command, then we simply verify that the output state is actually present: a move is not @@ -618,17 +643,17 @@ issuer of the CP is really paying back the face value.

    • The commercial paper must not be propagated by this transaction: it must be deleted, by the group having no output state. This prevents the same CP being considered redeemable multiple times.
    • -

      To calculate how much cash is moving, we use the sumCashOrNull utility method. Again, this is an extension method, +

      To calculate how much cash is moving, we use the sumCashBy utility function. Again, this is an extension function, so in Kotlin code it appears as if it was a method on the List<Cash.State> type even though JDK provides no such -method. In Java we see its true nature: it is actually a static method named CashKt.sumCashOrNull. This method simply -returns an Amount object containing the sum of all the cash states in the transaction output, or null if there were -no such states or if there were different currencies represented in the outputs! So we can see that this contract -imposes a limitation on the structure of a redemption transaction: you are not allowed to move currencies in the same -transaction that the CP does not involve. This limitation could be addressed with better APIs, if it were to be a -real limitation.

      +method. In Java we see its true nature: it is actually a static method named CashKt.sumCashBy. This method simply +returns an Amount object containing the sum of all the cash states in the transaction outputs that are owned by +that given public key, or throws an exception if there were no such states or if there were different currencies +represented in the outputs! So we can see that this contract imposes a limitation on the structure of a redemption +transaction: you are not allowed to move currencies in the same transaction that the CP does not involve. This +limitation could be addressed with better APIs, if it were to be a real limitation.

      Finally, we support an Issue command, to create new instances of commercial paper on the ledger. It likewise enforces various invariants upon the issuance.

      -

      This contract is extremely simple and does not implement all the business logic a real commercial paper lifecycle +

      This contract is simple and does not implement all the business logic a real commercial paper lifecycle management program would. For instance, there is no logic requiring a signature from the issuer for redemption: it is assumed that any transfer of money that takes place at the same time as redemption is good enough. Perhaps that is something that should be tightened. Likewise, there is no logic handling what happens if the issuer has gone @@ -639,159 +664,13 @@ contracts API.

      How to test your contract

      Of course, it is essential to unit test your new nugget of business logic to ensure that it behaves as you expect. -Although you can write traditional unit tests in Java, the platform also provides a domain specific language -(DSL) for writing contract unit tests that automates many of the common patterns. This DSL builds on top of JUnit yet -is a Kotlin DSL, and therefore this section will not show Java equivalent code (for Java unit tests you would not -benefit from the DSL and would write them by hand).

      -

      We start by defining a new test class, with a basic CP state:

      -
      -
      class CommercialPaperTests {
      -    val PAPER_1 = CommercialPaper.State(
      -            issuance = InstitutionReference(MEGA_CORP, OpaqueBytes.of(123)),
      -            owner = MEGA_CORP_KEY,
      -            faceValue = 1000.DOLLARS,
      -            maturityDate = TEST_TX_TIME + 7.days
      -    )
      -
      -    @Test
      -    fun key_mismatch_at_issue() {
      -        transactionGroup {
      -            transaction {
      -                output { PAPER_1 }
      -                arg(DUMMY_PUBKEY_1) { CommercialPaper.Commands.Issue() }
      -            }
      -
      -            expectFailureOfTx(1, "signed by the claimed issuer")
      -        }
      -    }
      -}
      -
      -
      -
      -

      We start by defining a commercial paper state. It will be owned by a pre-defined unit test party, affectionately -called MEGA_CORP (this constant, along with many others, is defined in TestUtils.kt). Due to Kotin’s extensive -type inference, many types are not written out explicitly in this code and it has the feel of a scripting language. -But the types are there, and you can ask IntelliJ to reveal them by pressing Alt-Enter on a “val” or “var” and selecting -“Specify type explicitly”.

      -

      There are a few things that are unusual here:

      -
        -
      • We can specify quantities of money by writing 1000.DOLLARS or 1000.POUNDS
      • -
      • We can specify quantities of time by writing 7.days
      • -
      • We can add quantities of time to the TEST_TX_TIME constant, which merely defines an arbitrary java.time.Instant
      • -
      -

      If you examine the code in the actual repository, you will also notice that it makes use of method names with spaces -in them by surrounding the name with backticks, rather than using underscores. We don’t show this here as it breaks the -doc website’s syntax highlighting engine.

      -

      The 1000.DOLLARS construct is quite simple: Kotlin allows you to define extension functions on primitive types like -Int or Double. So by writing 7.days, for instance, the compiler will emit a call to a static method that takes an int -and returns a java.time.Duration.

      -

      As this is JUnit, we must remember to annotate each test method with @Test. Let’s examine the contents of the first test. -We are trying to check that it’s not possible for just anyone to issue commercial paper in MegaCorp’s name. That would -be bad!

      -

      The transactionGroup function works the same way as the requireThat construct above.

      -
      -

      Note

      -

      This DSL is an example of what Kotlin calls a type safe builder, which you can read about in the -documentation for builders. You can mix and match -ordinary code inside such DSLs so please read the linked page to make sure you fully understand what they are capable -of.

      -
      -

      The code block that follows it is run in the scope of a freshly created TransactionGroupForTest object, which assists -you with building little transaction graphs and verifying them as a whole. Here, our “group” only actually has a -single transaction in it, with a single output, no inputs, and an Issue command signed by DUMMY_PUBKEY_1 which is just -an arbitrary public key. As the paper claims to be issued by MEGA_CORP, this doesn’t match and should cause a -failure. The expectFailureOfTx method takes a 1-based index (in this case we expect the first transaction to fail) -and a string that should appear in the exception message. Then it runs the TransactionGroup.verify() method to -invoke all the involved contracts.

      -

      It’s worth bearing in mind that even though this code may look like a totally different language to normal Kotlin or -Java, it’s actually not, and so you can embed arbitrary code anywhere inside any of these blocks.

      -

      Let’s set up a full trade and ensure it works:

      -
      -
        // Generate a trade lifecycle with various parameters.
      -  private fun trade(redemptionTime: Instant = TEST_TX_TIME + 8.days,
      -                    aliceGetsBack: Amount = 1000.DOLLARS,
      -                    destroyPaperAtRedemption: Boolean = true): TransactionGroupForTest {
      -    val someProfits = 1200.DOLLARS
      -    return transactionGroup {
      -        roots {
      -            transaction(900.DOLLARS.CASH owned_by ALICE label "alice's $900")
      -            transaction(someProfits.CASH owned_by MEGA_CORP_KEY label "some profits")
      -        }
      -
      -        // Some CP is issued onto the ledger by MegaCorp.
      -        transaction {
      -            output("paper") { PAPER_1 }
      -            arg(MEGA_CORP_KEY) { CommercialPaper.Commands.Issue() }
      -        }
      -
      -        // 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 {
      -            input("paper")
      -            input("alice's $900")
      -            output { 900.DOLLARS.CASH owned_by MEGA_CORP_KEY }
      -            output("alice's paper") { PAPER_1 owned_by ALICE }
      -            arg(ALICE) { Cash.Commands.Move }
      -            arg(MEGA_CORP_KEY) { CommercialPaper.Commands.Move }
      -        }
      -
      -        // 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(time = redemptionTime) {
      -            input("alice's paper")
      -            input("some profits")
      -
      -            output { aliceGetsBack.CASH owned_by ALICE }
      -            output { (someProfits - aliceGetsBack).CASH owned_by MEGA_CORP_KEY }
      -            if (!destroyPaperAtRedemption)
      -                output { PAPER_1 owned_by ALICE }
      -
      -            arg(MEGA_CORP_KEY) { Cash.Commands.Move }
      -            arg(ALICE) { CommercialPaper.Commands.Redeem }
      -        }
      -    }
      -}
      -
      -
      -
      -

      In this example we see some new features of the DSL:

      -
        -
      • The roots construct. Sometimes you don’t want to write transactions that laboriously issue everything you need -in a formally correct way. Inside roots you can create a bunch of states without any contract checking what you’re -doing. As states may not exist outside of transactions, each line inside defines a fake/invalid transaction with the -given output states, which may be labelled with a short string. Those labels can be used later to join transactions -together.
      • -
      • The .CASH suffix. This is a part of the unit test DSL specific to the cash contract. It takes a monetary amount -like 1000.DOLLARS and then wraps it in a cash ledger state, with some fake data.
      • -
      • The owned_by infix function. This is just -a normal function that we’re allowed to write in a slightly different way, which returns a copy of the cash state -with the owner field altered to be the given public key. ALICE is a constant defined by the test utilities that -is, like DUMMY_PUBKEY_1, just an arbitrary keypair.
      • -
      • We are now defining several transactions that chain together. We can optionally label any output we create. Obviously -then, the input method requires us to give the label of some other output that it connects to.
      • -
      • The transaction function can also be given a time, to override the default timestamp on a transaction.
      • -
      -

      The trade function is not itself a unit test. Instead it builds up a trade/transaction group, with some slight -differences depending on the parameters provided (Kotlin allows parameters to have default values). Then it returns -it, unexecuted.

      -

      We use it like this:

      -
      -
      @Test
      -fun ok() {
      -    trade().verify()
      -}
      -
      -@Test
      -fun not_matured_at_redemption() {
      -    trade(redemptionTime = TEST_TX_TIME + 2.days).expectFailureOfTx(3, "must have matured")
      -}
      -
      -
      -
      -

      That’s pretty simple: we just call verify in order to check all the transactions in the group. If any are invalid, -an exception will be thrown indicating which transaction failed and why. In the second case, we call expectFailureOfTx -again to ensure the third transaction fails with a message that contains “must have matured” (it doesn’t have to be -the exact message).

      +As contract code is just a regular Java function you could write out the logic entirely by hand in the usual +manner. But this would be inconvenient, and then you’d get bored of writing tests and that would be bad: you +might be tempted to skip a few.

      +

      To make contract testing more convenient Corda provides a language-like API for both Kotlin and Java that lets +you easily construct chains of transactions and verify that they either pass validation, or fail with a particular +error message.

      +

      Testing contracts with this domain specific language is covered in the separate tutorial, Writing a contract test.

      Adding a generation API to your contract

      @@ -811,18 +690,19 @@ like a module), the basic concept is the same: preparation of a transaction usin

      For our commercial paper contract however, the things that can be done with it are quite simple. Let’s start with a method to wrap up the issuance process:

      -
      fun generateIssue(issuance: InstitutionReference, faceValue: Amount, maturityDate: Instant): TransactionBuilder {
      +
      fun generateIssue(issuance: PartyAndReference, faceValue: Amount<Issued<Currency>>, maturityDate: Instant,
      +                  notary: Party): TransactionBuilder {
           val state = State(issuance, issuance.party.owningKey, faceValue, maturityDate)
      -    return TransactionBuilder(state, WireCommand(Commands.Issue, issuance.party.owningKey))
      +    return TransactionBuilder(notary = notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
       }
       

      We take a reference that points to the issuing party (i.e. the caller) and which can contain any internal -bookkeeping/reference numbers that we may require. Then the face value of the paper, and the maturity date. It -returns a TransactionBuilder. A TransactionBuilder is one of the few mutable classes the platform provides. -It allows you to add inputs, outputs and commands to it and is designed to be passed around, potentially between -multiple contracts.

      +bookkeeping/reference numbers that we may require. The reference field is an ideal place to put (for example) a +join key. Then the face value of the paper, and the maturity date. It returns a TransactionBuilder. +A TransactionBuilder is one of the few mutable classes the platform provides. It allows you to add inputs, +outputs and commands to it and is designed to be passed around, potentially between multiple contracts.

      Note

      Generation methods should ideally be written to compose with each other, that is, they should take a @@ -832,20 +712,26 @@ would just introduce complexity that isn’t likely to be worth it, so we re an issuer should issue the CP (starting out owned by themselves), and then sell it in a separate transaction.

      The function we define creates a CommercialPaper.State object that mostly just uses the arguments we were given, -but it fills out the owner field of the state to be the same public key as the issuing party. If the caller wants -to issue CP onto the ledger that’s immediately owned by someone else, they’ll have to create the state themselves.

      -

      The returned partial transaction has a WireCommand object as a parameter. This is a container for any object -that implements the Command interface, along with a key that is expected to sign this transaction. In this case, +but it fills out the owner field of the state to be the same public key as the issuing party.

      +

      The returned partial transaction has a Command object as a parameter. This is a container for any object +that implements the CommandData interface, along with a list of keys that are expected to sign this transaction. In this case, issuance requires that the issuing party sign, so we put the key of the party there.

      -

      The TransactionBuilder constructor we used above takes a variable argument list for convenience. You can pass in -any ContractStateRef (input), ContractState (output) or Command objects and it’ll build up the transaction +

      The TransactionBuilder has a convenience withItems method that takes a variable argument list. You can pass in +any StateAndRef (input), ContractState (output) or Command objects and it’ll build up the transaction for you.

      +

      There’s one final thing to be aware of: we ask the caller to select a notary that controls this state and +prevents it from being double spent. You can learn more about this topic in the Consensus model article.

      +
      +

      Note

      +

      For now, don’t worry about how to pick a notary. More infrastructure will come later to automate this +decision for you.

      +

      What about moving the paper, i.e. reassigning ownership to someone else?

      fun generateMove(tx: TransactionBuilder, paper: StateAndRef<State>, newOwner: PublicKey) {
      -    tx.addInputState(paper.ref)
      -    tx.addOutputState(paper.state.copy(owner = newOwner))
      -    tx.addArg(WireCommand(Commands.Move, paper.state.owner))
      +    tx.addInputState(paper)
      +    tx.addOutputState(paper.state.data.withOwner(newOwner))
      +    tx.addCommand(Command(Commands.Move(), paper.state.data.owner))
       }
       
      @@ -857,14 +743,17 @@ for the commercial paper contract.

      The paper is given to us as a StateAndRef<CommercialPaper.State> object. This is exactly what it sounds like: a small object that has a (copy of) a state object, and also the (txhash, index) that indicates the location of this state on the ledger.

      +

      We add the existing paper state as an input, the same paper state with the owner field adjusted as an output, +and finally a move command that has the old owner’s public key: this is what forces the current owner’s signature +to be present on the transaction, and is what’s checked by the contract.

      Finally, we can do redemption.

      @Throws(InsufficientBalanceException::class)
      -fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<Cash.State>>) {
      +fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: Wallet) {
           // Add the cash movement using the states in our wallet.
      -    Cash().generateSpend(tx, paper.state.faceValue, paper.state.owner, wallet)
      -    tx.addInputState(paper.ref)
      -    tx.addArg(WireCommand(CommercialPaper.Commands.Redeem, paper.state.owner))
      +    Cash().generateSpend(tx, paper.state.data.faceValue.withoutIssuer(), paper.state.data.owner, wallet.statesOfType<Cash.State>())
      +    tx.addInputState(paper)
      +    tx.addCommand(Command(Commands.Redeem(), paper.state.data.owner))
       }
       
      @@ -873,61 +762,67 @@ state on the ledger.

      issuer (i.e. the caller) must gather cash from its wallet and send the face value to the owner of the paper.

      Note

      -

      Exercise for the reader: In this early, simplified model of CP there is no built in support -for rollover. Extend the contract code to support rollover as well as redemption (reissuance of the paper with a -higher face value without any transfer of cash)

      +

      This contract has no explicit concept of rollover.

      -

      The wallet is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of cash states that are +

      The wallet is a concept that may be familiar from Bitcoin and Ethereum. It is simply a set of states (such as cash) that are owned by the caller. Here, we use the wallet to update the partial transaction we are handed with a movement of cash from the issuer of the commercial paper to the current owner. If we don’t have enough quantity of cash in our wallet, -an exception is thrown. And then we add the paper itself as an input, but, not an output (as we wish to delete it -from the ledger permanently). Finally, we add a Redeem command that should be signed by the owner of the commercial -paper.

      +an exception is thrown. Then we add the paper itself as an input, but, not an output (as we wish to remove it +from the ledger). Finally, we add a Redeem command that should be signed by the owner of the commercial paper.

      +
      +

      Warning

      +

      The amount we pass to the generateSpend function has to be treated first with withoutIssuer. +This reflects the fact that the way we handle issuer constraints is still evolving; the commercial paper +contract requires payment in the form of a currency issued by a specific party (e.g. the central bank, +or the issuers own bank perhaps). But the wallet wants to assemble spend transactions using cash states from +any issuer, thus we must strip it here. This represents a design mismatch that we will resolve in future +versions with a more complete way to express issuer constraints.

      +

      A TransactionBuilder is not by itself ready to be used anywhere, so first, we must convert it to something that is recognised by the network. The most important next step is for the participating entities to sign it using the signWith() method. This takes a keypair, serialises the transaction, signs the serialised form and then stores the signature inside the TransactionBuilder. Once all parties have signed, you can call TransactionBuilder.toSignedTransaction() -to get a SignedTransaction object. This is an immutable form of the transaction that’s ready for timestamping, -which can be done using a TimestamperClient. To learn more about that, please refer to the -Protocol state machines document.

      +to get a SignedTransaction object.

      You can see how transactions flow through the different stages of construction by examining the commercial paper unit tests.

      -
      -

      Non-asset-oriented based smart contracts

      -

      It is important to distinguish between the idea of a legal contract vs a code contract. In this document we use the -term contract as a shorthand for code contract: a small module of widely shared, simultaneously executed business -logic that uses standardised APIs and runs in a sandbox.

      +
      +

      How multi-party transactions are constructed and transmitted

      +

      OK, so now we know how to define the rules of the ledger, and we know how to construct transactions that satisfy +those rules ... and if all we were doing was maintaining our own data that might be enough. But we aren’t: Corda +is about keeping many different parties all in sync with each other.

      +

      In a classical blockchain system all data is transmitted to everyone and if you want to do something fancy, like +a multi-party transaction, you’re on your own. In Corda data is transmitted only to parties that need it and +multi-party transactions are a way of life, so we provide lots of support for managing them.

      +

      You can learn how transactions are moved between peers and taken through the build-sign-notarise-broadcast +process in a separate tutorial, Protocol state machines.

      +
      +
      +

      Non-asset-oriented smart contracts

      Although this tutorial covers how to implement an owned asset, there is no requirement that states and code contracts must be concerned with ownership of an asset. It is better to think of states as representing useful facts about the -world, and (code) contracts as imposing logical relations on how facts combine to produce new facts.

      -

      For example, in the case that the transfer of an asset cannot be performed entirely on-ledger, one possible usage of -the model is to implement a delivery-vs-payment lifecycle in which there is a state representing an intention to trade -and two other states that can be interpreted by off-ledger platforms as firm instructions to move the respective asset -or cash - and a final state in which the exchange is marked as complete. The key point here is that the two off-platform -instructions form pa rt of the same Transaction and so either both are signed (and can be processed by the off-ledger -systems) or neither are.

      -

      As another example, consider multi-signature transactions, a feature which is commonly used in Bitcoin to implement -various kinds of useful protocols. This technique allows you to lock an asset to ownership of a group, in which a -threshold of signers (e.g. 3 out of 4) must all sign simultaneously to enable the asset to move. It is initially -tempting to simply add this as another feature to each existing contract which someone might want to treat in this way. -But that could lead to unnecessary duplication of work.

      -

      A better approach is to model the fact of joint ownership as a new contract with its own state. In this approach, to -lock up your commercial paper under multi-signature ownership you would make a transaction that looks like this:

      -
        -
      • Input: the CP state
      • -
      • Output: a multi-sig state that contains the list of keys and the signing threshold desired (e.g. 3 of 4). The state has a hash of H.
      • -
      • Output: the same CP state, with a marker that says a state with hash H must exist in any transaction that spends it.
      • -
      -

      The CP contract then needs to be extended only to verify that a state with the required hash is present as an input. -The logic that implements measurement of the threshold, different signing combinations that may be allowed etc can then -be implemented once in a separate contract, with the controlling data being held in the named state.

      -

      Future versions of the prototype will explore these concepts in more depth.

      +world, and (code) contracts as imposing logical relations on how facts combine to produce new facts. Alternatively +you can imagine that states are like rows in a relational database and contracts are like stored procedures and +relational constraints.

      +

      When writing a contract that handles deal-like entities rather than asset-like entities, you may wish to refer +to “Interest Rate Swaps” and the accompanying source code. Whilst all the concepts are the same, deals are +typically not splittable or mergeable and thus you don’t have to worry much about grouping of states.

      +
      +
      +

      Making things happen at a particular time

      +

      It would be nice if you could program your node to automatically redeem your commercial paper as soon as it matures. +Corda provides a way for states to advertise scheduled events that should occur in future. Whilst this information +is by default ignored, if the corresponding Cordapp is installed and active in your node, and if the state is +considered relevant by your wallet (e.g. because you own it), then the node can automatically begin the process +of creating a transaction and taking it through the life cycle. You can learn more about this in the article +“Event scheduling”.

      Clauses

      -

      Instead of structuring contracts as a single entity, they can be broken down into reusable chunks known as clauses. -This idea is addressed in the next tutorial, “Writing a contract using clauses”.

      +

      It is typical for slightly different contracts to have lots of common logic that can be shared. For example, the +concept of being issued, being exited and being upgraded are all usually required in any contract. Corda calls these +frequently needed chunks of logic “clauses”, and they can simplify development considerably.

      +

      Clauses and how to use them are addressed in the next tutorial, “Writing a contract using clauses”.