Skip to content

Commit

Permalink
Moves code sections in tutorials to code files.
Browse files Browse the repository at this point in the history
  • Loading branch information
Joel Dudley authored Oct 1, 2017
1 parent 4d40279 commit 4641d3c
Show file tree
Hide file tree
Showing 42 changed files with 2,286 additions and 2,100 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ object ContractUpgradeFlow {
*
* This flow will NOT initiate the upgrade process. To start the upgrade process, see [Initiate].
*/
// DOCSTART 1
@StartableByRPC
class Authorise(
val stateAndRef: StateAndRef<*>,
private val upgradedContractClass: Class<out UpgradedContract<*, *>>
) : FlowLogic<Void?>() {
// DOCEND 1
@Suspendable
override fun call(): Void? {
val upgrade = upgradedContractClass.newInstance()
Expand All @@ -43,10 +45,12 @@ object ContractUpgradeFlow {
* Deauthorise a contract state upgrade.
* This will remove the upgrade authorisation from persistent store (and prevent any further upgrade)
*/
// DOCSTART 2
@StartableByRPC
class Deauthorise(val stateRef: StateRef) : FlowLogic<Void?>() {
@Suspendable
override fun call(): Void? {
//DOCEND 2
serviceHub.contractUpgradeService.removeAuthorisedContractUpgrade(stateRef)
return null
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,16 @@ interface NetworkMapCache {
data class Modified(override val node: NodeInfo, val previousNode: NodeInfo) : MapChange()
}

// DOCSTART 1
/**
* A list of notary services available on the network.
*
* Note that the identities are sorted based on legal name, and the ordering might change once new notaries are introduced.
*/
// TODO this list will be taken from NetworkParameters distributed by NetworkMap.
val notaryIdentities: List<Party>
// DOCEND 1

/** Tracks changes to the network map cache. */
val changed: Observable<MapChange>
/** Future to track completion of the NetworkMapService registration. */
Expand Down Expand Up @@ -87,8 +90,10 @@ interface NetworkMapCache {
/** Returns information about the party, which may be a specific node or a service */
fun getPartyInfo(party: Party): PartyInfo?

// DOCSTART 2
/** Gets a notary identity by the given name. */
fun getNotary(name: CordaX500Name): Party? = notaryIdentities.firstOrNull { it.name == name }
// DOCEND 2

/** Checks whether a given party is an advertised notary identity. */
fun isNotary(party: Party): Boolean = party in notaryIdentities
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
import kotlin.test.assertNull

// DOCSTART 3
class ResolveTransactionsFlowTest {
lateinit var mockNet: MockNetwork
lateinit var notaryNode: StartedNode<MockNetwork.MockNode>
Expand Down Expand Up @@ -53,6 +54,8 @@ class ResolveTransactionsFlowTest {
mockNet.stopNodes()
unsetCordappPackages()
}
// DOCEND 3


// DOCSTART 1
@Test
Expand Down
Binary file modified docs/source/_static/corda-cheat-sheet.pdf
Binary file not shown.
2 changes: 2 additions & 0 deletions docs/source/api-index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ This section describes the APIs that are available for the development of CorDap
api-vault-query
api-transactions
api-flows
api-service-hub
api-rpc
api-core-types

Before reading this page, you should be familiar with the :doc:`key concepts of Corda <key-concepts>`.
Expand Down
10 changes: 4 additions & 6 deletions docs/source/api-rpc.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,18 @@ The key RPC operations exposed by the node are:
* Extract states from the node's vault based on a query criteria
* ``CordaRPCOps.vaultTrackBy``
* As above, but also returns an observable of future states matching the query
* ``CordaRPCOps.verifiedTransactions``
* Extract all transactions from the node's local storage, as well as an observable of all future transactions
* ``CordaRPCOps.networkMapUpdates``
* ``CordaRPCOps.networkMapFeed``
* A list of network nodes, and an observable of changes to the network map
* ``CordaRPCOps.registeredFlows``
* See a list of registered flows on the node
* ``CordaRPCOps.startFlowDynamic``
* Start one of the node's registered flows
* ``CordaRPCOps.startTrackedFlowDynamic``
* As above, but also returns a progress handle for the flow
* ``CordaRPCOps.nodeIdentity``
* Returns the node's identity
* ``CordaRPCOps.nodeInfo``
* Returns information about the node
* ``CordaRPCOps.currentNodeTime``
* Returns the node's current time
* Returns the current time according to the node's clock
* ``CordaRPCOps.partyFromKey/CordaRPCOps.wellKnownPartyFromX500Name``
* Retrieves a party on the network based on a public key or X500 name
* ``CordaRPCOps.uploadAttachment``/``CordaRPCOps.openAttachment``/``CordaRPCOps.attachmentExists``
Expand Down
6 changes: 2 additions & 4 deletions docs/source/api-service-hub.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,5 @@ Additional, ``ServiceHub`` exposes the following properties:

* ``ServiceHub.loadState`` and ``ServiceHub.toStateAndRef`` to resolve a ``StateRef`` into a ``TransactionState`` or
a ``StateAndRef``
* ``ServiceHub.toSignedTransaction`` to sign a ``TransactionBuilder`` and convert it into a ``SignedTransaction``
* ``ServiceHub.createSignature`` and ``ServiceHub.addSignature`` to create and add signatures to a ``SignedTransaction``

Finally, ``ServiceHub`` exposes notary identity key via ``ServiceHub.notaryIdentityKey``.
* ``ServiceHub.signInitialTransaction`` to sign a ``TransactionBuilder`` and convert it into a ``SignedTransaction``
* ``ServiceHub.createSignature`` and ``ServiceHub.addSignature`` to create and add signatures to a ``SignedTransaction``
124 changes: 61 additions & 63 deletions docs/source/contract-upgrade.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,95 +7,93 @@
Upgrading contracts
===================

While every care is taken in development of contract code,
inevitably upgrades will be required to fix bugs (in either design or implementation).
Upgrades can involve a substitution of one version of the contract code for another or changing
to a different contract that understands how to migrate the existing state objects. State objects
refer to the contract code (by hash) they are intended for, and even where state objects can be used
with different contract versions, changing this value requires issuing a new state object.
While every care is taken in development of contract code, inevitably upgrades will be required to fix bugs (in either
design or implementation). Upgrades can involve a substitution of one version of the contract code for another or
changing to a different contract that understands how to migrate the existing state objects. When state objects are
added as outputs to transactions, they are linked to the contract code they are intended for via the
``StateAndContract`` type. Changing a state's contract only requires substituting one ``ContractClassName`` for another.

Workflow
--------

Here's the workflow for contract upgrades:

1. Two banks, A and B negotiate a trade, off-platform

2. Banks A and B execute a protocol to construct a state object representing the trade, using contract X, and include it in a transaction (which is then signed and sent to the consensus service).
1. Banks A and B negotiate a trade, off-platform

3. Time passes.
2. Banks A and B execute a flow to construct a state object representing the trade, using contract X, and include it in
a transaction (which is then signed and sent to the consensus service)

4. The developer of contract X discovers a bug in the contract code, and releases a new version, contract Y. The developer will then notify all existing users (e.g. via a mailing list or CorDapp store) to stop their nodes from issuing further states with contract X.
3. Time passes

5. Banks A and B review the new contract via standard change control processes and identify the contract states they agree to upgrade (they may decide not to upgrade some contract states as these might be needed for some other obligation contract).
4. The developer of contract X discovers a bug in the contract code, and releases a new version, contract Y. The
developer will then notify all existing users (e.g. via a mailing list or CorDapp store) to stop their nodes from
issuing further states with contract X

6. Banks A and B instruct their Corda nodes (via RPC) to be willing to upgrade state objects of contract X, to state objects for contract Y using agreed upgrade path.
5. Banks A and B review the new contract via standard change control processes and identify the contract states they
agree to upgrade (they may decide not to upgrade some contract states as these might be needed for some other
obligation contract)

7. One of the parties initiates (``Initiator``) an upgrade of state objects referring to contract X, to a new state object referring to contract Y.
6. Banks A and B instruct their Corda nodes (via RPC) to be willing to upgrade state objects with contract X to state
objects with contract Y using the agreed upgrade path

8. A proposed transaction ``Proposal``, taking in the old state and outputting the reissued version, is created and signed with the node's private key.
7. One of the parties (the ``Initiator``) initiates a flow to replace state objects referring to contract X with new
state objects referring to contract Y

9. The ``Initiator`` node sends the proposed transaction, along with details of the new contract upgrade path its proposing, to all participants of the state object.
8. A proposed transaction (the ``Proposal``), with the old states as input and the reissued states as outputs, is
created and signed with the node's private key

10. Each counterparty ``Acceptor`` verifies the proposal, signs or rejects the state reissuance accordingly, and sends a signature or rejection notification back to the initiating node.
9. The ``Initiator`` node sends the proposed transaction, along with details of the new contract upgrade path that it
is proposing, to all participants of the state object

11. If signatures are received from all parties, the initiating node assembles the complete signed transaction and sends it to the consensus service.
10. Each counterparty (the ``Acceptor``s) verifies the proposal, signs or rejects the state reissuance accordingly, and
sends a signature or rejection notification back to the initiating node
11. If signatures are received from all parties, the ``Initiator`` assembles the complete signed transaction and sends
it to the notary

Authorising upgrade
-------------------
Authorising an upgrade
----------------------
Each of the participants in the state for which the contract is being upgraded will have to instruct their node that
they agree to the upgrade before the upgrade can take place. The ``ContractUpgradeFlow`` is used to manage the
authorisation process. Each node administrator can use RPC to trigger either an ``Authorise`` or a ``Deauthorise`` flow
for the state in question.

Each of the participants in the upgrading contract will have to instruct their node that they are willing to upgrade the state object before the upgrade.
The ``ContractUpgradeFlow`` is used to manage the authorisation records. The administrator can use RPC to trigger either an ``Authorise`` or ``Deauthorise`` flow.

.. container:: codeset

.. sourcecode:: kotlin
.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt
:language: kotlin
:start-after: DOCSTART 1
:end-before: DOCEND 1
:dedent: 4

/**
* Authorise a contract state upgrade.
* This will store the upgrade authorisation in persistent store, and will be queried by [ContractUpgradeFlow.Acceptor] during contract upgrade process.
* Invoking this flow indicates the node is willing to upgrade the [StateAndRef] using the [UpgradedContract] class.
* This method will NOT initiate the upgrade process. To start the upgrade process, see [Initiator].
*/
@StartableByRPC
class Authorise(
val stateAndRef: StateAndRef<*>,
private val upgradedContractClass: Class<out UpgradedContract<*, *>>
) : FlowLogic<Void?>()
/**
* Deauthorise a contract state upgrade.
* This will remove the upgrade authorisation from persistent store (and prevent any further upgrade)
*/
@StartableByRPC
class Deauthorise(
val stateRef: StateRef
) : FlowLogic< Void?>()
.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/flows/ContractUpgradeFlow.kt
:language: kotlin
:start-after: DOCSTART 2
:end-before: DOCEND 2
:dedent: 4

Proposing an upgrade
--------------------
After all parties have authorised the contract upgrade for the state, one of the contract participants can initiate the
upgrade process by triggering the ``ContractUpgradeFlow.Initiate`` flow. ``Initiate`` creates a transaction including
the old state and the updated state, and sends it to each of the participants. Each participant will verify the
transaction, create a signature over it, and send the signature back to the initiator. Once all the signatures are
collected, the transaction will be notarised and persisted to every participant's vault.

After all parties have registered the intention of upgrading the contract state, one of the contract participants can initiate the upgrade process by triggering the ``Initiator`` contract upgrade flow.
The ``Initiator`` will create a new state and sent to each participant for signatures, each of the participants (Acceptor) will verify, sign the proposal and return to the initiator.
The transaction will be notarised and persisted once every participant verified and signed the upgrade proposal.

Examples
--------

Lets assume Bank A has entered into an agreement with Bank B, and the contract is translated into contract code ``DummyContract`` with state object ``DummyContractState``.
Example
-------
Suppose Bank A has entered into an agreement with Bank B which is represented by the state object
``DummyContractState`` and governed by the contract code ``DummyContract``. A few days after the exchange of contracts,
the developer of the contract code discovers a bug in the contract code.

A few days after the exchange of contracts, the developer of the contract code discovered a bug/misrepresentation in the contract code.
Bank A and Bank B decided to upgrade the contract to ``DummyContractV2``
Bank A and Bank B decide to upgrade the contract to ``DummyContractV2``:

1. Developer will create a new contract extending the ``UpgradedContract`` class, and a new state object ``DummyContractV2.State`` referencing the new contract.
1. The developer creates a new contract ``DummyContractV2`` extending the ``UpgradedContract`` class, and a new state
object ``DummyContractV2.State`` referencing the new contract.

.. literalinclude:: /../../test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt
.. literalinclude:: /../../testing/test-utils/src/main/kotlin/net/corda/testing/contracts/DummyContractV2.kt
:language: kotlin
:start-after: DOCSTART 1
:end-before: DOCEND 1

2. Bank A will instruct its node to accept the contract upgrade to ``DummyContractV2`` for the contract state.
2. Bank A instructs its node to accept the contract upgrade to ``DummyContractV2`` for the contract state.

.. container:: codeset

Expand All @@ -105,9 +103,9 @@ Bank A and Bank B decided to upgrade the contract to ``DummyContractV2``
val rpcA = rpcClient.proxy()
rpcA.startFlow(ContractUpgradeFlow.Authorise(<<StateAndRef of the contract state>>, DummyContractV2::class.java))

3. Bank B now initiate the upgrade Flow, this will send a upgrade proposal to all contract participants.
Each of the participants of the contract state will sign and return the contract state upgrade proposal once they have validated and agreed with the upgrade.
The upgraded transaction state will be recorded in every participant's node at the end of the flow.
3. Bank B initiates the upgrade flow, which will send an upgrade proposal to all contract participants. Each of the
participants of the contract state will sign and return the contract state upgrade proposal once they have validated
and agreed with the upgrade. The upgraded transaction will be recorded in every participant's node by the flow.

.. container:: codeset

Expand Down
6 changes: 3 additions & 3 deletions docs/source/corda-repo-layout.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ The Corda repository comprises the following folders:
* **buildSrc** contains necessary gradle plugins to build Corda
* **client** contains libraries for connecting to a node, working with it remotely and binding server-side data to
JavaFX UI
* **confidential-identities** contains experimental support for confidential identities on the ledger
* **config** contains logging configurations and the default node configuration file
* **core** containing the core Corda libraries such as crypto functions, types for Corda's building blocks: states,
contracts, transactions, attachments, etc. and some interfaces for nodes and protocols
* **docs** contains the Corda docsite in restructured text format as well as the built docs in html. The docs can be
accessed via ``/docs/index.html`` from the root of the repo
* **docs** contains the Corda docsite in restructured text format
* **experimental** contains platform improvements that are still in the experimental stage
* **finance** defines a range of elementary contracts (and associated schemas) and protocols, such as abstract fungible
assets, cash, obligation and commercial paper
Expand All @@ -20,7 +20,7 @@ The Corda repository comprises the following folders:
* **node** contains the core code of the Corda node (eg: node driver, node services, messaging, persistence)
* **node-api** contains data structures shared between the node and the client module, e.g. types sent via RPC
* **samples** contains all our Corda demos and code samples
* **test-utils** contains some utilities for unit testing contracts ( the contracts testing DSL) and protocols (the
* **testing** contains some utilities for unit testing contracts (the contracts testing DSL) and flows (the
mock network) implementation
* **tools** contains the explorer which is a GUI front-end for Corda, and also the DemoBench which is a GUI tool that
allows you to run Corda nodes locally for demonstrations
Expand Down
Loading

0 comments on commit 4641d3c

Please sign in to comment.