diff --git a/README.md b/README.md index eba677a651..0257115d5f 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ Corda is an open source blockchain project, designed for business from the start ## Useful links * [Project Website](https://corda.net) -* [Mailing Lists](https://www.corda.net/mailing-lists/) +* [Mailing List](https://groups.io/g/corda-dev/) * [Documentation](https://docs.corda.net) * [Stack Overflow Tag](https://stackoverflow.com/questions/tagged/corda) * [Slack Channel](https://slack.corda.net/) diff --git a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt index c7651da4cb..8c4be6530f 100644 --- a/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt +++ b/core/src/main/kotlin/net/corda/core/internal/CordaUtils.kt @@ -57,3 +57,16 @@ fun Class>.isIdempotentFlow(): Boolean { internal fun SignedTransaction.pushToLoggingContext() { MDC.put("tx_id", id.toString()) } + +/** + * List implementation that applies the expensive [transform] function only when the element is accessed and caches calculated values. + * Size is very cheap as it doesn't call [transform]. + */ +class LazyMappedList(val originalList: List, val transform: (T, Int) -> U) : AbstractList() { + private val partialResolvedList = MutableList(originalList.size) { null } + + override val size = originalList.size + + override fun get(index: Int) = partialResolvedList[index] + ?: transform(originalList[index], index).also { computed -> partialResolvedList[index] = computed } +} diff --git a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt index aef380e153..811b3dfab6 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/MerkleTransaction.kt @@ -6,9 +6,11 @@ import net.corda.core.contracts.* import net.corda.core.contracts.ComponentGroupEnum.* import net.corda.core.crypto.* import net.corda.core.identity.Party +import net.corda.core.internal.LazyMappedList import net.corda.core.internal.uncheckedCast import net.corda.core.serialization.* import net.corda.core.utilities.OpaqueBytes +import net.corda.core.utilities.lazyMapped import java.security.PublicKey import java.util.function.Predicate import kotlin.reflect.KClass @@ -69,21 +71,29 @@ abstract class TraversableTransaction(open val componentGroups: List deserialiseComponentGroup(clazz: KClass, groupEnum: ComponentGroupEnum, attachmentsContext: Boolean = false): List { + val group = componentGroups.firstOrNull { it.groupIndex == groupEnum.ordinal } + + if (group == null || group.components.isEmpty()) { + return emptyList() + } + + // If the componentGroup is a [LazyMappedList] it means that the original deserialized version is already available. + val components = group.components + if (components is LazyMappedList<*, OpaqueBytes>) { + return components.originalList as List + } + val factory = SerializationFactory.defaultFactory val context = factory.defaultContext.let { if (attachmentsContext) it.withAttachmentsClassLoader(attachments) else it } - val group = componentGroups.firstOrNull { it.groupIndex == groupEnum.ordinal } - return if (group != null && group.components.isNotEmpty()) { - group.components.mapIndexed { internalIndex, component -> - try { - factory.deserialize(component, clazz.java, context) - } catch (e: MissingAttachmentsException) { - throw e - } catch (e: Exception) { - throw Exception("Malformed transaction, $groupEnum at index $internalIndex cannot be deserialised", e) - } + + return components.lazyMapped { component, internalIndex -> + try { + factory.deserialize(component, clazz.java , context) + } catch (e: MissingAttachmentsException) { + throw e + } catch (e: Exception) { + throw Exception("Malformed transaction, $groupEnum at index $internalIndex cannot be deserialised", e) } - } else { - emptyList() } } @@ -105,14 +115,14 @@ abstract class TraversableTransaction(open val componentGroups: List Command(commandData, signersList[leafIndices[index]]) } + commandDataList.lazyMapped { commandData, index -> Command(commandData, signersList[leafIndices[index]]) } } else { // It is a WireTransaction // or a FilteredTransaction with no Commands (in which case group is null). check(commandDataList.size == signersList.size) { "Invalid Transaction. Sizes of CommandData (${commandDataList.size}) and Signers (${signersList.size}) do not match" } - commandDataList.mapIndexed { index, commandData -> Command(commandData, signersList[index]) } + commandDataList.lazyMapped { commandData, index -> Command(commandData, signersList[index]) } } } } @@ -335,7 +345,7 @@ class FilteredTransaction internal constructor( private fun expectedNumOfCommands(publicKey: PublicKey, commandSigners: ComponentGroup?): Int { checkAllComponentsVisible(SIGNERS_GROUP) if (commandSigners == null) return 0 - fun signersKeys (internalIndex: Int, opaqueBytes: OpaqueBytes): List { + fun signersKeys(internalIndex: Int, opaqueBytes: OpaqueBytes): List { try { return SerializedBytes>(opaqueBytes.bytes).deserialize() } catch (e: Exception) { @@ -344,7 +354,7 @@ class FilteredTransaction internal constructor( } return commandSigners.components - .mapIndexed { internalIndex, opaqueBytes -> signersKeys(internalIndex, opaqueBytes) } + .mapIndexed { internalIndex, opaqueBytes -> signersKeys(internalIndex, opaqueBytes) } .filter { signers -> publicKey in signers }.size } diff --git a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt index 757f86d6af..6ff8983745 100644 --- a/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt +++ b/core/src/main/kotlin/net/corda/core/transactions/WireTransaction.kt @@ -14,6 +14,7 @@ import net.corda.core.node.services.AttachmentId import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.serialize import net.corda.core.utilities.OpaqueBytes +import net.corda.core.utilities.lazyMapped import java.security.PublicKey import java.security.SignatureException import java.util.function.Predicate @@ -50,7 +51,8 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr @Deprecated("Required only in some unit-tests and for backwards compatibility purposes.", ReplaceWith("WireTransaction(val componentGroups: List, override val privacySalt: PrivacySalt)"), DeprecationLevel.WARNING) @DeleteForDJVM - @JvmOverloads constructor( + @JvmOverloads + constructor( inputs: List, attachments: List, outputs: List>, @@ -127,17 +129,19 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr networkParameters: NetworkParameters? ): LedgerTransaction { // Look up public keys to authenticated identities. - val authenticatedArgs = commands.map { - val parties = it.signers.mapNotNull { pk -> resolveIdentity(pk) } - CommandWithParties(it.signers, parties, it.value) + val authenticatedArgs = commands.lazyMapped { cmd, _ -> + val parties = cmd.signers.mapNotNull { pk -> resolveIdentity(pk) } + CommandWithParties(cmd.signers, parties, cmd.value) } - val resolvedInputs = inputs.map { ref -> + val resolvedInputs = inputs.lazyMapped { ref, _ -> resolveStateRef(ref)?.let { StateAndRef(it, ref) } ?: throw TransactionResolutionException(ref.txhash) } - val resolvedReferences = references.map { ref -> + val resolvedReferences = references.lazyMapped { ref, _ -> resolveStateRef(ref)?.let { StateAndRef(it, ref) } ?: throw TransactionResolutionException(ref.txhash) } - val attachments = attachments.map { resolveAttachment(it) ?: throw AttachmentResolutionException(it) } + val attachments = attachments.lazyMapped { att, _ -> + resolveAttachment(att) ?: throw AttachmentResolutionException(att) + } val ltx = LedgerTransaction(resolvedInputs, outputs, authenticatedArgs, attachments, id, notary, timeWindow, privacySalt, networkParameters, resolvedReferences) checkTransactionSize(ltx, networkParameters?.maxTransactionSize ?: 10485760) return ltx @@ -151,13 +155,22 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr remainingTransactionSize -= size } + // This calculates a value that is slightly lower than the actual re-serialized version. But it is stable and does not depend on the classloader. + fun componentGroupSize(componentGroup: ComponentGroupEnum): Int { + return this.componentGroups.firstOrNull { it.groupIndex == componentGroup.ordinal }?.let { cg -> cg.components.sumBy { it.size } + 4 } ?: 0 + } + // Check attachments size first as they are most likely to go over the limit. With ContractAttachment instances // it's likely that the same underlying Attachment CorDapp will occur more than once so we dedup on the attachment id. ltx.attachments.distinctBy { it.id }.forEach { minus(it.size) } + + // TODO - these can be optimized by creating a LazyStateAndRef class, that just stores (a pointer) the serialized output componentGroup from the previous transaction. minus(ltx.references.serialize().size) minus(ltx.inputs.serialize().size) - minus(ltx.commands.serialize().size) - minus(ltx.outputs.serialize().size) + + // For Commands and outputs we can use the component groups as they are already serialized. + minus(componentGroupSize(COMMANDS_GROUP)) + minus(componentGroupSize(OUTPUTS_GROUP)) } /** @@ -253,18 +266,19 @@ class WireTransaction(componentGroups: List, val privacySalt: Pr notary: Party?, timeWindow: TimeWindow?, references: List = emptyList()): List { + val serialize = { value: Any, _: Int -> value.serialize() } val componentGroupMap: MutableList = mutableListOf() - if (inputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(INPUTS_GROUP.ordinal, inputs.map { it.serialize() })) - if (references.isNotEmpty()) componentGroupMap.add(ComponentGroup(REFERENCES_GROUP.ordinal, references.map { it.serialize() })) - if (outputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.map { it.serialize() })) + if (inputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(INPUTS_GROUP.ordinal, inputs.lazyMapped(serialize))) + if (references.isNotEmpty()) componentGroupMap.add(ComponentGroup(REFERENCES_GROUP.ordinal, references.lazyMapped(serialize))) + if (outputs.isNotEmpty()) componentGroupMap.add(ComponentGroup(OUTPUTS_GROUP.ordinal, outputs.lazyMapped(serialize))) // Adding commandData only to the commands group. Signers are added in their own group. - if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(COMMANDS_GROUP.ordinal, commands.map { it.value.serialize() })) - if (attachments.isNotEmpty()) componentGroupMap.add(ComponentGroup(ATTACHMENTS_GROUP.ordinal, attachments.map { it.serialize() })) - if (notary != null) componentGroupMap.add(ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary.serialize()))) - if (timeWindow != null) componentGroupMap.add(ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow.serialize()))) + if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(COMMANDS_GROUP.ordinal, commands.map { it.value }.lazyMapped(serialize))) + if (attachments.isNotEmpty()) componentGroupMap.add(ComponentGroup(ATTACHMENTS_GROUP.ordinal, attachments.lazyMapped(serialize))) + if (notary != null) componentGroupMap.add(ComponentGroup(NOTARY_GROUP.ordinal, listOf(notary).lazyMapped(serialize))) + if (timeWindow != null) componentGroupMap.add(ComponentGroup(TIMEWINDOW_GROUP.ordinal, listOf(timeWindow).lazyMapped(serialize))) // Adding signers to their own group. This is required for command visibility purposes: a party receiving // a FilteredTransaction can now verify it sees all the commands it should sign. - if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(SIGNERS_GROUP.ordinal, commands.map { it.signers.serialize() })) + if (commands.isNotEmpty()) componentGroupMap.add(ComponentGroup(SIGNERS_GROUP.ordinal, commands.map { it.signers }.lazyMapped(serialize))) return componentGroupMap } } diff --git a/core/src/main/kotlin/net/corda/core/utilities/KotlinUtils.kt b/core/src/main/kotlin/net/corda/core/utilities/KotlinUtils.kt index 26d4fbce11..82702514b6 100644 --- a/core/src/main/kotlin/net/corda/core/utilities/KotlinUtils.kt +++ b/core/src/main/kotlin/net/corda/core/utilities/KotlinUtils.kt @@ -1,8 +1,10 @@ @file:KeepForDJVM + package net.corda.core.utilities import net.corda.core.DeleteForDJVM import net.corda.core.KeepForDJVM +import net.corda.core.internal.LazyMappedList import net.corda.core.internal.concurrent.get import net.corda.core.internal.uncheckedCast import net.corda.core.serialization.CordaSerializable @@ -136,6 +138,12 @@ fun Future.getOrThrow(timeout: Duration? = null): V = try { throw e.cause!! } +/** + * Returns a [List] implementation that applies the expensive [transform] function only when an element is accessed and then caches the calculated values. + * Size is very cheap as it doesn't call [transform]. + */ +fun List.lazyMapped(transform: (T, Int) -> U): List = LazyMappedList(this, transform) + private const val MAX_SIZE = 100 private val warnings = Collections.newSetFromMap(object : LinkedHashMap() { override fun removeEldestEntry(eldest: MutableMap.MutableEntry?) = size > MAX_SIZE diff --git a/core/src/test/kotlin/net/corda/core/internal/JarSignatureCollectorTest.kt b/core/src/test/kotlin/net/corda/core/internal/JarSignatureCollectorTest.kt index b7a50cee46..4c124e81b7 100644 --- a/core/src/test/kotlin/net/corda/core/internal/JarSignatureCollectorTest.kt +++ b/core/src/test/kotlin/net/corda/core/internal/JarSignatureCollectorTest.kt @@ -36,7 +36,6 @@ class JarSignatureCollectorTest { fun beforeClass() { dir.generateKey(ALICE, ALICE_PASS, ALICE_NAME.toString()) dir.generateKey(BOB, BOB_PASS, BOB_NAME.toString()) - dir.generateKey(CHARLIE, CHARLIE_PASS, CHARLIE_NAME.toString(), "EC") (dir / "_signable1").writeLines(listOf("signable1")) (dir / "_signable2").writeLines(listOf("signable2")) @@ -131,16 +130,14 @@ class JarSignatureCollectorTest { assertFailsWith { dir.getJarSigners(FILENAME) } } - // Signing using EC algorithm produced JAR File spec incompatible signature block (META-INF/*.EC) which is anyway accepted by jarsiner, see [JarSignatureCollector] + // Signing with EC algorithm produces META-INF/*.EC file name not compatible with JAR File Spec however it's compatible with java.util.JarVerifier + // and our JarSignatureCollector @Test - fun `one signer with EC sign algorithm`() { + fun `one signer with EC algorithm`() { + dir.generateKey(CHARLIE, CHARLIE_PASS, CHARLIE_NAME.toString(), "EC") dir.createJar(FILENAME, "_signable1", "_signable2") - val charlieKey = dir.signJar(FILENAME, CHARLIE, CHARLIE_PASS) - assertEquals(setOf(charlieKey), dir.getJarSigners(FILENAME).toSet()) // We only reused CHARLIE's distinguished name, so the keys will be different. - - (dir / "my-dir").createDirectory() - dir.updateJar(FILENAME, "my-dir") - assertEquals(setOf(charlieKey), dir.getJarSigners(FILENAME).toSet()) // Unsigned directory is irrelevant. + val key = dir.signJar(FILENAME, CHARLIE, CHARLIE_PASS) + assertEquals(listOf(key), dir.getJarSigners(FILENAME)) // We only used CHARLIE's distinguished name, so the keys will be different. } private fun signAsAlice() = dir.signJar(FILENAME, ALICE, ALICE_PASS) diff --git a/core/src/test/kotlin/net/corda/core/transactions/CompatibleTransactionTests.kt b/core/src/test/kotlin/net/corda/core/transactions/CompatibleTransactionTests.kt index 6ca1cf810b..ba89c5a1a5 100644 --- a/core/src/test/kotlin/net/corda/core/transactions/CompatibleTransactionTests.kt +++ b/core/src/test/kotlin/net/corda/core/transactions/CompatibleTransactionTests.kt @@ -138,7 +138,7 @@ class CompatibleTransactionTests { timeWindowGroup, signersGroup ) - assertFails { WireTransaction(componentGroupsB, privacySalt) } + assertFails { WireTransaction(componentGroupsB, privacySalt).attachments.toList() } // Malformed tx - duplicated component group detected. val componentGroupsDuplicatedCommands = listOf( diff --git a/core/src/test/kotlin/net/corda/core/utilities/LazyMappedListTest.kt b/core/src/test/kotlin/net/corda/core/utilities/LazyMappedListTest.kt new file mode 100644 index 0000000000..3c20aaa876 --- /dev/null +++ b/core/src/test/kotlin/net/corda/core/utilities/LazyMappedListTest.kt @@ -0,0 +1,35 @@ +package net.corda.core.utilities + +import org.junit.Test +import kotlin.test.assertEquals + +class LazyMappedListTest { + + @Test + fun `LazyMappedList works`() { + val originalList = (1 until 10).toList() + + var callCounter = 0 + + val lazyList = originalList.lazyMapped { value, _ -> + callCounter++ + value * value + } + + // No transform called when created. + assertEquals(0, callCounter) + + // No transform called when calling 'size'. + assertEquals(9, lazyList.size) + assertEquals(0, callCounter) + + // Called once when getting an element. + assertEquals(16, lazyList[3]) + assertEquals(1, callCounter) + + // Not called again when getting the same element. + assertEquals(16, lazyList[3]) + assertEquals(1, callCounter) + } + +} diff --git a/docs/source/api-flows.rst b/docs/source/api-flows.rst index 0b3a1a12b7..747e5276f9 100644 --- a/docs/source/api-flows.rst +++ b/docs/source/api-flows.rst @@ -716,28 +716,36 @@ HTTP, database and other calls to external resources are allowed in flows. Howev Concurrency, Locking and Waiting -------------------------------- -This is an advanced topic. Because Corda is designed to: +Corda is designed to: -* run many flows in parallel, -* may persist flows to storage and resurrect those flows much later, -* (in the future) migrate flows between JVMs, +* run many flows in parallel +* persist flows to storage and resurrect those flows much later +* (in the future) migrate flows between JVMs -flows should avoid use of locks and typically not even attempt to interact with objects shared between flows (except -``ServiceHub`` and other carefully crafted services such as Oracles. See :doc:`oracles`). -Locks will significantly reduce the scalability of the node, in the best case, and can cause the node to deadlock if they -remain locked across flow context switch boundaries (such as sending and receiving -from peers discussed above, and the sleep discussed below). +Because of this, care must be taken when performing locking or waiting operations. -If you need activities that are scheduled, you should investigate the use of ``SchedulableState``. -However, we appreciate that Corda support for some more advanced patterns is still in the future, and if there is a need -for brief pauses in flows then you should use ``FlowLogic.sleep`` in place of where you might have used ``Thread.sleep``. -Flows should expressly not use ``Thread.sleep``, since this will prevent the node from processing other flows -in the meantime, significantly impairing the performance of the node. -Even ``FlowLogic.sleep`` is not to be used to create long running flows, since the Corda ethos is for short lived flows -(otherwise upgrading nodes or CorDapps is much more complicated), or as a substitute to using the ``SchedulableState`` scheduler. +Locking +^^^^^^^ +Flows should avoid using locks or interacting with objects that are shared between flows (except for ``ServiceHub`` and other +carefully crafted services such as Oracles. See :doc:`oracles`). Locks will significantly reduce the scalability of the +node, and can cause the node to deadlock if they remain locked across flow context switch boundaries (such as when sending +and receiving from peers, as discussed above, or sleeping, as discussed below). -Currently the ``finance`` package uses ``FlowLogic.sleep`` to make several attempts at coin selection, where necessary, -when many states are soft locked and we wish to wait for those, or other new states in their place, to become unlocked. +Waiting +^^^^^^^ +A flow can wait until a specific transaction has been received and verified by the node using `FlowLogic.waitForLedgerCommit`. +Outside of this, scheduling an activity to occur at some future time should be achieved using ``SchedulableState``. + +However, if there is a need for brief pauses in flows, you have the option of using ``FlowLogic.sleep`` in place of where you +might have used ``Thread.sleep``. Flows should expressly not use ``Thread.sleep``, since this will prevent the node from +processing other flows in the meantime, significantly impairing the performance of the node. + +Even ``FlowLogic.sleep`` should not be used to create long running flows or as a substitute to using the ``SchedulableState`` +scheduler, since the Corda ethos is for short-lived flows (long-lived flows make upgrading nodes or CorDapps much more +complicated). + +For example, the ``finance`` package currently uses ``FlowLogic.sleep`` to make several attempts at coin selection when +many states are soft locked, to wait for states to become unlocked: .. literalinclude:: ../../finance/src/main/kotlin/net/corda/finance/contracts/asset/cash/selection/AbstractCashSelection.kt :language: kotlin diff --git a/docs/source/api-testing.rst b/docs/source/api-testing.rst index 80b8134827..5435e2f875 100644 --- a/docs/source/api-testing.rst +++ b/docs/source/api-testing.rst @@ -211,7 +211,7 @@ You manually process received messages as follows: * ``StartedMockNode.pumpReceive()`` processes a single message from the node's queue * ``MockNetwork.runNetwork()`` processes all the messages in every node's queue until there are no further messages to - process + process When ``networkSendManuallyPumped`` is set to ``true``, nodes will automatically process the messages they receive. You can block until all messages have been processed using ``MockNetwork.waitQuiescent()``. diff --git a/docs/source/corda-network/governance-guidelines.md b/docs/source/corda-network/governance-guidelines.md new file mode 100644 index 0000000000..7d9adebc42 --- /dev/null +++ b/docs/source/corda-network/governance-guidelines.md @@ -0,0 +1,545 @@ +Corda Network Foundation : Governance Guidelines +==================================================== + +23 October 2018 + +Version 0.95 + +DRAFT for discussion + +This is a set of governance guidelines for the Corda Network Foundation. It provides a framework for the Foundation’s +Board, to steer and govern Corda Network effectively to realise its potential. It is not a set of binding legal obligations. + +1 Background to Corda and the Network +===================================== + +Corda allows multiple independent applications and private networks to coexist, each with their own business models and +membership criteria, yet linked by the same underlying network (‘Corda Network’). This Network enables ‘interoperability’, +the exchange of data or assets via a secure, efficient ‘internet layer’, in a way that isn’t possible with competing +permissioned distributed ledger technologies or legacy systems. + +Corda Network operates the protocol of Corda currently, and is always expected to. The protocol is currently +specified in the Corda Open Source Project codebase, but later may be formalised in a protocol specification document, +which then will become canonical. + +1.1 Reason for a Corda Network Foundation +----------------------------------------- +R3 has set up and governs by default Corda Network currently (along with Corda). This includes making key decisions +around establishing, maintaining and updating standards, policies, and procedures for participation in, and use of, +Corda Network. + +However, it is critically important that a commercial entity should not control Corda Network going forwards. It should +be governed transparently (to its Participants), with a fair and stable structure. Analysis and feedback show +that Corda Network will be most effectively governed via a Foundation, a not-for-profit, independent entity in which +Network Participants elect, and can be elected to, a governing Board. + +A Foundation will enable Network Participants to be involved with, and also understand, how decisions are made (including +around issues of identity and permission), building trust and engagement from a wide range of stakeholders. This will +bring about the best decisions and outcomes for the Network’s long-term success. + +In other words, to achieve the community's objective of Corda ubiquity, it is necessary to put in place a governance +structure which explicitly limits R3’s control of Corda Network, and enables this ubiquity. + +2 The Corda Network Foundation +============================== + +2.1 Mission and Values +---------------------- +Following on from the Corda introduction and technical white papers, we see the mission of the Corda Network Foundation +to achieve the vision of Corda - whereby the state of transactions and agreements of business partners can be recorded +in a single global database, ending the need for costly reconciliation and error correction, while maintaining privacy. +Further details of the vision are laid out in the +[Corda Introductory White Paper](https://www.corda.net/content/corda-platform-whitepaper.pdf). + +Achieving this vision in its full ubiquity will involve running and maintaining a stable and secure Network with open +and fair governance, while also promoting the Network so as to ensure its more widespread use. + +Following on this, the Corda Network Foundation shall embody the following qualities in executing its mission: + +* Fairness and openness – Participants can join the Network and make up the Network’s governing board, elected through a +straightforward voting process. +* Democracy and transparency – Key decisions and rationale are shared openly with Participants. +* Stability (with a long-term view) with flexibility – Board directors’ terms will last three years with a staggered +board, and the governance model will be flexible to adapt where required. +* Efficiency – Staying a lean organisation, sufficient to commission and monitor an Operator to run any services, +physical infrastructure, or operational processes that may be needed to achieve the vision of Corda. Provide adequate +support, through advisory committees. +* Cost effectiveness - Funding received through participation fees pays for an Operator to run the Network securely, and +the Foundation shall not be a profit-making entity. +* Independence – Corda Network Foundation makes its own decisions (within the law), and is not following another +entity’s rules. + +More specifically, the Foundation shall focus on the following commitments over the long-term: + +* Maintain the long-term standards, services and open governance model of the Network, ensuring it continues to be +updated to the current Corda protocol version. +* Hold the Trust Root for the Network, used for creation of operational certificates, independently of the Operator. +* Commission the provision and operation of infrastructure and services for the Network, both of technical services, and +infrastructure needed for meetings, events and collaborative discussions, and provide structure around the business and +technical governance of the Network. +* Facilitate a diverse and vibrant community of industry experts, Corda contributors, users and services, including +developers, service and solution providers and end users. +* Set minimum standards for the external provision of notary and oracle services. +* Enable the ubiquity and utility of Corda throughout all applicable industries and commercial use cases. +* Balance the divergent interests of a wide range of stakeholders, including business network operators, Corda +customers, open source developers, and R3’s shareholders. + +2.2 Structure of the Foundation +------------------------------- +The Foundation shall be a not-for-profit entity created exclusively to execute the mission set out in this Constitution. +With the advice of international lawyers, this is a ‘Stichting’ domiciled in Holland – a legal entity suited for +governance activities, able to act commercially, with limited liability but no shareholders, capital or dividends. + +The Foundation is defined in a set of Articles of Association and By-laws. + +The Foundation governance bodies shall include: + +1. A **Governing Board** (‘the Board’) of 11 representatives (‘Directors’) with privileges and responsibilities as set out +in section 3. +2. A **Technical Advisory Committee** (‘the TAC’), comprised of representatives of Participant organisations with +responsibilities set out in section 6.2. +3. A **Governance Advisory Committee**, comprised of representatives of Participant organisations with responsibilities +set out in section 6.3. +4. A **Network Operator** (‘the Operator’), charging the Foundation reasonable costs for providing network and +administration services, paid by the Foundation through membership funds, and accountable directly to the Board, set +out in section 7. + +Operating on behalf of: + +* A **General Membership** (‘the Participant Community’), which is open to any organisation participating in Corda Network, +and with privileges and responsibilities as set out in section 6. + +Any change to the structure of the Foundation is a constitutional change, described in section 5.1. + +3 Governing Board +================= + +3.1 Role of the Board +--------------------- +The goal of the Board is primarily to ensure the stable and secure operation of the Network, as well as to achieve the +vision of Corda laid out in section 2.1. The fundamental responsibility of directors appointed to the Board is to +exercise their business judgement to act in what they believe to be the best interests of the Network, taking account +of the interests of the Network community as a whole (rather than any one individual interest). + +Directors are expected to comply with the Conflict of Interest policy, which includes a responsibility to disclose +promptly any conflicts that may arise, and meet the expected standards specified in the Code of Conduct Guidelines for +ethical conduct and breach reporting. + +The Board is the formal decision-making authority of the Foundation, and actions of the Board reflect its collective +decision making. + +3.2 Relationship of the Board with the Operator +----------------------------------------------- +It is the duty of the Board to monitor the Operator’s performance to ensure that the Network operates in an effective, +efficient and ethical manner. The Board will also be responsible for overseeing the Operator in the development of the +Network’s strategic and tactical plans, ensuring that they will result in broad and open adoption of Corda. The Operator +is responsible to the Board for the execution of day to day operations, and the implementation of strategic and tactical +change. + +3.3 Composition and Establishment of the Board +---------------------------------------------- +### 3.3.1 Size +The Board shall consist of 11 voting members (‘Directors’) in total, to allow broad representation but maintain an agile +decision-making ability. The selection process (using the Participant Community) is intended to ensure that the Board is +composed of members who display diversity in geography, culture, skills, experience and perspective, and that the +abilities and interests of Directors are aligned with those of Corda. + +R3 shall have the ongoing right to appoint two Directors, as the firm which developed Corda and funded the initial +construction of the Network. It represents the interests of its large and diverse alliance of commercial organisations, +financial institutions, and regulatory bodies. Similarly to the rest of the board, the Directors will have three-year +terms (unless the director resigns or leaves for another reason) and can be re-appointed without limit. Appointment will +be effective immediately. + +The Chair of the board will be elected for a one year term by a vote of the Directors of the Board, at the first Board +meeting following the Board election. + +#### 3.3.2 Participation Criteria +Participants shall be directed to vote to ensure that the Board is composed of Directors who in the aggregate produce +the broadest diversity on the Board, consistent with meeting the other criteria. In addition, the Board is to be +comprised of individuals who can demonstrate to Participants they meet the following requirements: + +* Hold an understanding and appreciation of the Corda protocol and community purpose. +* Have an awareness of cultural and geographic perspectives. +* Demonstrate integrity, intelligence and objectivity. +* Can work and communicate in written and spoken English. + +To promote diversity, the following guidelines are adopted, in particular for steady-state governance (recognising that +these may not be possible to fulfil during the transition period): + +* No corporate group of participants may have more than one Director. In the event of votes for two different candidates +representing the same overall corporate group, the candidate with the most votes shall be considered. +* Of the nine Directors, there should not be more than three Directors from any broad industry classification, according to +company classification data. +* Of the nine Directors, there should not be more than three Directors from any continent (one must be based in the Americas, +Europe/Africa and Asia, to ensure geographic diversity. +* Of the nine Directors, there should not be more than three Directors representing any Corporate Group with more than +100,000 employees. +* There is no restriction of re-election of Directors or the Chair of the Board. + +### 3.3.3 Establishment of the Board +#### 3.3.3.1 Pre-Foundation +Initially R3 shall govern the Network to ensure rapid progress on its implementation. Once the Foundation is set-up and +at least three business networks are conducting live transactions using the network with at least three Participants each, the +'transition period' of one year will commence. +#### 3.3.3.2 Transition: Initial set-up of Foundation Board: +For the transition year, the first three business networks shall have the right to choose three Participants, to +represent the interests of the business network. One of each of these must be based in the Americas, Europe/Africa and +Asia, to ensure geographic diversity, if the pool Participants allows. Each selected Participant will appoint a +Director, to sit on the Board, making nine Directors in addition to the two Directors from R3. + +After this start-up period, there will be a vote for Board Directors. + +For the first election only, of the nine vacant seats, three will be for a duration of one year, three for two years, and +three for three years. This will introduce a staggered board, so there is greater continuity at the end of each term. +Candidates with the most votes will fill the three-year seats first, followed by two-year and then one-year seats. In all other +respects, the first election will follow the steady state process. +#### 3.3.3.3 Steady-State +1. Participants may nominate candidates for Director election. Appointments to the nine rotating seats of the Board will be +by vote of the Participants, with three seats up for election each year. Any seats vacated mid-term will also be +elected at the same time. R3 may not put forward candidates for the nine rotating seats, and these may not be held by +R3 employees. +2. Candidates will create a personal statement and short biography, which will be shared with all Participants. +3. Participants may each cast up to three votes for three separate candidates. +4. Subject to meeting certain criteria (including diversity of geography and industry), the most popular candidates +will be appointed as Directors. +5. Candidates will be considered in sequence from most popular to least, and if a seat is vacant according to the +diversity criteria in section 3.3.2, the candidate will be allocated to it. This may mean that occasionally a less +popular candidate fills a seat instead of a more popular one. +6. R3 shall appoint Directors to the two remaining seats, when appropriate. +#### 3.3.4 Removal from the Board and Re-election. +Apart from the three-year expiry, Directors can otherwise leave the Board by resignation, prolonged non-attendance of +board meetings of more than six months, death, or if necessary, removal by a Mandatory Governance Event. In any case, a +vacant seat will be contested at the next annual election. + +3.4 Conduct of Board Meetings +----------------------------- +Attendance may be in person or by video-conference. + +The Board shall meet not less than every six months, and may meet on the request of any Director, but not more than every +two months. At least two weeks’ notice shall be given to Directors. By exception, the Chair may convene an emergency +meeting with minimal notice, appropriate to the situation in the Chair's judgement. + +The Board shall consider all Governance Events proposed since the previous meeting, except for an emergency convening. + +Board meetings shall be limited to the Board representatives, and shall follow the requirements for quorum and voting +outlined in this Constitution. + +The Board may decide whether to allow one named representative to attend as an alternate, and typically these shall be +allowed. + +The Board meetings shall be conducted in private, but in the interest of transparency, public minutes shall be +published within two weeks following their approval by the Board. + +Participants who do not have representation on the Board may request an observer to be present at a Board meeting. +This is subject to a lottery held one week prior to the meeting, a limit of 20 observer places, and a limit of one +observer per unrepresented Participant. Observers may participate in discussions but shall not participate in any Board +vote, and may be asked to join by video-conference if there are logistical constraints. + +4 Relation of the Foundation to Business Networks +=================================================== + +The global Network shall support the operation of any business networks which may be formed by industry-specific +operators on top of the Network. The Board shall ensure that there is a clear separation between areas of governance +for the Foundation and Network outlined in this document, and for individual business networks. + +Additionally, the structure and control processes defined for the Foundation shall be documented and made available +under a Creative Commons license, both for reuse by business network operators if business networks need a similar +governance structure, and so that such governance layers are complementary and not contradictory. + +5 Governance Events +===================== + +All formal changes to the Network and the Foundation shall be controlled through a formal Governance Event process, and +the right to initiate this shall be held by all Directors and Participants. In the event of disruptive behaviour by an +individual Participant or group of Participants, this right may be curtailed, as described in 5.2.5. + +5.1 Types of Governance Events +------------------------------ +There are three types of change that affect the Network and the Foundation, which require a controlled change process +and a vote described in 5.5, and are defined as Governance Events: + +1. All changes to the Stichting Articles of Association and By-laws are defined as Constitutional Governance Events. +2. All changes to Network participation criteria, charges, budgets, change management process and other business areas not +defined in Articles of Association or By-laws are defined as Mandatory Governance Events in section 5.2. The Board shall +vote to accept or reject all such Mandatory Governance Events, and the outcomes are binding on Participants and the +Operator for implementation. +3. All changes to technical parameters and notary criteria, which affect the nodes of participants, are defined as +Advisory Governance Events in section 5.3. While the Operator can implement these without Board approval, it may ask the +Board to provide an advisory (non-binding) vote. Conversely, the Board may require that it is given the opportunity to +provide an advisory vote. + +Any other changes in the day to day internal implementation of network services by the Operator, which do not require +changes to be implemented on the nodes of participants, are out of scope as Governance Events. + +All Constitutional, Mandatory and Advisory Governance Events shall be supported by a formal proposal, using standard +structured documents and containing all relevant background information, to create an efficient process both for the +submitter and the Board. +Depending on the content of the Governance Event proposal, the Board or Operator may rely on the Governance or Technical +Advisory Committee to provide due diligence and make a recommendation for implementation. + +For all Governance Events, decisions and the rationale for the decision shall be published transparently. + +5.2 Mandatory Governance Events +------------------------------- +### 5.2.1 Access Standards +The Corda system can be accessed by using software which implements the set of technical protocols which define +compatibility (see 5.3.1) above). The reference implementation of this software is open source and freely accessible at +[www.corda.net](https://www.corda.net). + +To join the Network, a participant running Corda compatible software also needs a unique and real-world identity. The +Foundation shall enforce this access requirement through the issuance of PKI certificates. Corda has a primary objective +to facilitate automation of real-world contracts between real-world parties, and has a particular requirement to ensure +that identities on the Network are unique and that all participants understand the basis on which they have been issued. +The Foundation shall govern the operation of the technical infrastructure to enable a good level of service for identity +issuance. + +The access criteria for proving real world identity shall be defined by the Board and shall be transparent and objective. +Any party which can demonstrate they meet these criteria will be issued a certificate without prejudice. The goal to +ensure that the Operator which manages the issuance of the network certificates cannot act arbitrarily or +discriminatory. But lawful requests from regulatory authorities of the Foundation’s jurisdiction shall be accepted. + +These criteria may be subject to change over time to deal with changing circumstances, like regulatory requirements. +However, the changes shall be subject to Mandatory Governance Events. In this way the Network is able to provide its +participants with a strong and fair identity framework. + +Arbitration, suspension, and in extreme circumstances, revocation (for example for illegal behaviour or when a +participant no longer meets the standards set forth) shall be managed through an Emergency Governance Event, set out in +5.4. + +#### 5.2.2 Budget, Expenditure and Participation Fees +The Board shall annually prepare and approve a budget for the operations of the Foundation, taking into account the +not-for-profit status of the Foundation and the mission to promote the Corda Ecosystem. + +The Foundation shall charge a fee for Membership, as described in section 6.1. + +The Operator shall charge the Foundation for services that the Operator provides under the requirements of the contract +with the Foundation, including management of Participants, Network participation and access services, Network map +and Operator-provided notary services. The Operator may also provide fee-based services that are supplementary to those +needed to participate on the Network. + +#### 5.2.3 Change of Network Operator +For three years upon establishment of the Foundation, R3 will undertake the role of Operator. Annually thereafter, the +Board will approve the appointment of the Operator, which may be changed with a Mandatory Governance Event and vote. +As noted, the Foundation shall hold the Trust Root, and the Operator and any services they operate shall be provisioned +with intermediate certificates that derive from this. The Operator must enter into an escrow arrangement upon +appointment, so that existing certificates continue to work, certificate revocation lists continue to be published, and +there is no disruption to Participants if the Operator is changed. + +#### 5.2.4 Change Management Process +The Network will periodically require participating nodes to implement change. A change notification and management +process shall be defined and communicated; and any change to the change management process shall be the subject of a +Mandatory Governance Event. + +#### 5.2.5 Other Mandatory Governance Events +Restrictions on individual Participants or a group to initiate Governance Events; in the event of disruptive behaviour. + +Audit: the Board may request an audit of the activities and services provided by the Operator, no more frequently than +every year, unless an emergency audit is authorised through a Mandatory Governance Event. + +Marketing, Trademark and Branding: R3 shall commit to license the Corda trademark to the Foundation. The Foundation +shall manage its own brand and any trademarks created. + +Certifications: Where the Foundation provides standards for certification of organisations, individuals or technologies, +the Board shall approve the standards and processes for certification. + +Change to the arbitration and dispute resolution process shall be the subject of a Mandatory Governance Event. + +Policies covering areas of operation not covered by the Constitution (e.g. code of conduct for Board Directors). + +5.3 Advisory Governance Events +------------------------------ +#### 5.3.1 Technical Standards +There is a set of technical standards, such as ‘network parameters’, which all Corda Network nodes need to comply with +in order to guarantee technical compatibility to other nodes and services within the Network. While Corda has stability +and backwards compatibility as key design goals, there may be circumstances under which these standards will need to +change. Where these changes require participants in the Network to update to remain compatible, these changes will be +subject to Governance Events. + +Changes to technical standards, such as some network parameters, shall require formal design processes, and the Operator may +choose to delegate technical due diligence to the Technical Advisory Committee prior to formally accepting a change to +the technical standards. + +The Corda open source software is the reference implementation for the core technical standards adopted for the Network. +Corda implementations and distributions can vary in their internal details, but their core interfaces and Corda protocol +implementation must conform to this standard to be compatible with the Network. + +#### 5.3.2 Consensus Standards +The Foundation shall set minimum standards for notary clusters, to allow their use across different business +applications. The Operator shall ensure that standards are followed by notary service providers, and shall operate a +framework of audit and assessment, review, feedback, and certification, covering the following: + +1. Technical standards, such as meeting strict requirements for high-availability and data replication/security and +performance. +2. Compliance with necessary laws and regulations (for example privacy and data retention regulations) in the +jurisdictions in which they operate. +3. Availability for independent audits upon request by the Board. + +Additionally, the Operator shall manage a reference distributed notary service for the Network, using a Board-approved +crash or Byzantine fault tolerant (BFT) consensus algorithm, with nodes provided by a minimum number of identified and +independent entities. + +#### 5.3.3 Dispute Resolution Process +Disputes between Participants arising from the operation of a Corda application are anticipated to be resolved by the +business network operator, or directly if no business network is involved. If necessary, Participants may escalate to +the Board by creating an Advisory Governance Event. + +5.4 Emergency Governance Events +------------------------------- +Certain Network incidents, which could impact one or more Network participants and that would be the subject of +Mandatory or Advisory Governance Events, shall require immediate resolution. In these cases, the Operator may make +emergency changes, but these shall be subject to post-event evaluation and standard Governance Event processing. Areas +of control that are the subject of Mandatory Governance Events are not expected to require emergency remediation, but +the Operator shall be entitled to make emergency changes to preserve the stability and integrity of the Network. + +5.5 Voting +---------- +All Constitutional, Mandatory and Advisory Governance Events outlined in sections 5.2 and 5.3 shall be presented to the +Board for voting. The representatives of the Board shall vote on a one vote per Director basis to approve or reject the +Governance Event. + +Quorum for the Board shall require two thirds of the Directors to vote. Abstention is not a vote. The Board may continue +to meet if quorum is not met, but shall be prevented from making any decisions at the meeting. Decisions by electronic +vote without a meeting shall require a vote by two thirds majority of all Directors. + +Provided quorum is met, Constitutional Governance Events shall require a three quarters majority vote, and Mandatory +Governance Events shall require a two thirds majority vote. + +In the event of a tied vote (the odd number of representatives is intended to avoid tied votes) the vote of the Chair +shall carry the vote. If the Chair does not vote in the case of a tied vote, the Event will not be passed. + +All Governance Events proposed for consideration by the Board at a meeting shall be circulated in draft form to the +members of the Board at least one week prior to the date of the meeting, and the text of such draft events may be altered +at the meeting. + +The Foundation may chose to implement the tracking and voting for Governance Events using an on-ledger Corda application +in an attempt to simplify governance, provide transparency and lower costs, provided the application has been tested +thoroughly and has sufficient manual override controls. + +6 Participation +================= + +6.1 General Membership +---------------------- +Participation is open to any potential participant on the Network, subject to meeting normal Network access conditions +described in section 5.2.1, and paying a nominal annual participation fee to cover both the operational costs of Network +services and the Foundation, and to ensure that its activities are sufficiently resourced. + +The Participant Community have the right to: + +1. Propose a formal Governance Event to the Board for voting. This must meet the appropriate standards and formats. +2. Request observer representation at a board meeting subject to logistical constraints. +3. Utilise any brand and marketing materials that may be provided by the Foundation to Participants. +4. Identify themselves as participants of the Foundation. +5. Vote in the periodic election of a new Board. +6. Participate in conferences, projects and initiatives of the Foundation. Numbers of participants and any additional +costs will depend on the individual event. +7. Receive an identity necessary to operate a Corda node on the Network. +8. Use the Network for live business activities running 'in production'. + +6.2 Technical Advisory Committee +-------------------------------- +The Technical Advisory Committee shall have limited participants appointed directly by the Board. Its mandate and +charter will be set by the Board. It shall act directly on the instructions of the Board or the Operator, which shall +set expected deliverables and timelines. It shall focus on specific technical topics and may have responsibility for +the following: + +1. Advise on technical decisions for the Operator. +2. Advising the Board in technical matters. +3. Provide feedback on the technical roadmap for Corda, from real-world and practical experience gained from observing +the operation of the Network. +4. Conducting open design reviews and soliciting public input for technical proposals. +5. Contributing to the Corda open source community from a Network perspective, to ensure that Corda retains a coherent, +elegant and practical system design + +6.3 Governance Advisory Committee +--------------------------------- +The Governance Advisory Committee shall have limited participants appointed directly by the board. Its purpose is to +recommend actions to the Board for approval on non-technical matters, where additional support is helpful. This may +include decisions on: + +1. Operator Due Diligence +2. Identity and Permissions +3. Risks and Escalations +4. Interacting with Regulators +5. Complaints and Whistle-blowing + +7 The Corda Network Operator +============================ + +In order to pursue the mission of the Foundation as set out in section 1, there will need to be a set of operational +activities, including technical activities such as hosting services, marketing activities, community management and +promotion. These activities shall be funded through the participation fees and overseen by the Board, and they will +require operational staffing by the Operator. It is not envisaged (at least during the first year) that the Corda +Network Foundation will need separate staff. Administrative operations and meeting facilities will be provided by the +Operator. + +The Operator shall invoice the Foundation for the costs of operating the Network and minor administrative expenses, +initially on a cost-plus basis, and subject to annual review. Corda Network identity and map technical services +have been designed to be highly cacheable, and low-cost in operation. + +For the first three years, R3 shall act as the Operator. + +8 Costs and Participation Fees +============================== + +8.1 Costs +--------- +In line with the mission and values of the Foundation, the Network Foundation is not a profit seeking entity. But the +Foundation needs to provide governance and technical services, and these will incur costs. The Foundation maintains these +cost principles, as ideals but not contractual standards: + +1. Costs for all services should be borne by all users of those services. +2. One group of participants should not subsidise another. +3. The costs shall be tightly managed, and the Foundation shall seek to provide the most cost-effective implementation +of all of its own administration, governance and technical services. +4. Costs of one service should not be subsidised by another. +5. The Foundation's cost model should be public, to demonstrate that the costs could not reasonably be lower. + +8.2 Participation Fee +--------------------- +The Foundation shall meet costs by levying a participation fee and notary fee for all Participants. The participation +fee will be independent of organisation size and number of transactions on Corda, to reflect the underlying cost of +identity issuance. + +The fee shall be based on the number of Participants divided by an estimate of the cost of running the Foundation, +which is set out in section 7. There may be variance in the fee depending on whether the Participant is indirectly using a +Corda Network-powered application, and therefore the services which the Participant is able to access. + +Such fees shall be detailed in a separate schedule to be updated annually and approved by the Board by a Mandatory +Governance Event. + +The Operator may agree to provide the Foundation with a start-up commercial loan, in order to allow the Foundation to +cap fees for Participants initially. This will allow early widespread adoption, when early participant numbers will not +offset fixed operating costs. In this case, the fees will not fall to steady-state levels until the loan has been repaid. + +Subsidiaries of large organisations shall apply for membership separately, since the model for Corda usage is for one +identity per legal entity, unless varied by Mandatory Governance Event. The fee and voting right shall apply to each +subsidiary individually. + +The fee applies even if the Participants chooses not to operate a Corda node on the Network. Therefore, Participants +can be potential or active participants. + +8.3 Notary Fee +-------------- +Transaction notary fees will be charged separately, on a per-use basis. This reflects the variable cost of providing +notary services, with a wide orders-of-magnitude disparity between frequent and infrequent participant transaction +volumes. As a principle, notary fees shall not subsidise participation fees, nor vice versa. + +9 Community +=========== +Corda is a collaborative effort, and part of the Foundation’s mission is to help create and foster a technical community +that will benefit all Corda solution providers and users. As such, the Foundation will work to encourage further +participation of leading Participants of the ecosystem, including developers, service and solution providers and end +users. This community shall work towards furthering the adoption of Corda, and contribute to the specific capabilities +identified in the technical white paper. + +The Corda technical community should be broad and open, encouraging participation and active conversations on the +technology and applications, but this cannot be mandated by the Foundation. + +9.1 Non-Discrimination +---------------------- +The Foundation will welcome any organization able to meet the Participation criteria, regardless of competitive +interests with other Participants. The Board shall not seek to exclude any Participant for any reasons other than those +that are reasonable, explicit and applied on a non-discriminatory basis to all Participants. + +END diff --git a/docs/source/corda-network/governance-structure.md b/docs/source/corda-network/governance-structure.md new file mode 100644 index 0000000000..7405b42406 --- /dev/null +++ b/docs/source/corda-network/governance-structure.md @@ -0,0 +1,31 @@ +Governance Structure +==================== + +It is critically important that a commercial entity should not control Corda Network going forwards, and that it should +be governed transparently, with a fair and representative structure that can deliver a stable operating environment for +its members in the long term. + +A separate entity called Corda Network Foundation will be set up, using a not-for-profit legal entity type known as a +Stichting, residing in the Netherlands. This type is suited for governance activities, able to act commercially, with +limited liability but no shareholders, capital or dividends. Its constitution is defined in a set of Articles of +Association and By-laws. + +A Foundation will enable Network members to be involved with, and also understand, how decisions are made (including +around issues of identity and permission), building trust and engagement from a wide range of stakeholders. We believe +this will bring about the best decisions and outcomes for the Network’s long-term success. + +Its governance bodies shall include: + +- A **Governing Board** (‘the Board’) of 11 representatives (‘Directors’). +- A **Technical Advisory Committee** (‘the TAC’), comprised of representatives of Participant organisations. +- A **Governance Advisory Committee**, comprised of representatives of Participant organisations. +- A **Network Operator** (‘the Operator’), charging the Foundation reasonable costs for providing network and administration +services, paid by the Foundation through membership funds, and accountable directly to the Board. + +Operating on behalf of: + +- **Participants** (‘Participants’), open to any legal entity participating in Corda Network, and independent of R3 +alliance membership. + +For more information about the intended governance of the network, please refer to the [Corda Network Foundation : +Governance Guidelines](governance-guidelines.md) document. \ No newline at end of file diff --git a/docs/source/corda-network/index.md b/docs/source/corda-network/index.md new file mode 100644 index 0000000000..beee40efd5 --- /dev/null +++ b/docs/source/corda-network/index.md @@ -0,0 +1,59 @@ +Corda Network +============== + +Introduction to Corda Network +----------------------------- +Corda Network consists of Corda nodes operated by network participants, in which business transactions are created and +validated via Corda Distributed Applications (CorDapps) running on these nodes. Each node is identified by means of a +certificate issued by the Network's Certificate Authority, and will also be identifiable on a network map. + +Corda Network enables interoperability – the exchange of data or assets via a secure, efficient internet layer – in a way +that isn't possible with competing permissioned distributed ledger technologies or legacy systems. + +The network is due to go live in December 2018, and initially it will be governed by R3. An independent, not-for-profit +Foundation is currently being set-up which is intended to govern the Network from mid 2019, after a transition period +when control moves entirely to the Foundation. See the [governance model](governance-structure.md) for more detail. + +The Network will comprise many sub-groups many sub-groups of participants running particular CorDapps (sometimes but not +always referred to as 'business networks'), and such groups will often have a co-ordinating party (the 'Business +Network Operator') who manages the distribution of the app and rules (including around membership) for its use. + +Corda Network will support the operation of business networks by industry-specific operators within the Network. There +will be a clear separation between areas of governance for the Network and for individual business networks. For example, +rules around membership of business networks will be controlled by its Business Network Operators. + +Key services +============ + +Doorman +------- +The Doorman controls admissions and exits of Participants into and out of Corda Network. The Service receives Certificate +Signing Requests (CSRs) from prospective Network Participants (sometimes via a Business Network Operator) and reviews the +information submitted. A digitally signed Participation Certificate is returned if: + +* The prospective Corda Network Participant meets the requirements specified in the documentation; +* Evidence is provided by the Participant or Business Network Operator of agreement to the Corda Network Participant Terms +of Use. + +The Corda Network Participant can then use the Participation Certificate to register itself with the R3 Network Map Service. + +Network Map +----------- +The Network Map Service accepts digitally signed documents describing network routing and identifying information from +Participants, based on the Participation Certificates signed by the Doorman, and makes this information available to all +Corda Network Participants. + +Notary +------ +Corda design separates correctness consensus from uniqueness consensus, and the latter is provided by one or more Notary +services. The Notary will digitally sign a transaction presented to it - provided no transaction referring to +any of the same inputs has been previously signed by the Notary, and the transaction timestamp is within bounds. + +Business Network Operators and Network Participants may choose to enter into legal agreements which rely on the presence +of such digital signatures when determining whether a transaction to which they are party, or upon the details of which they +otherwise rely, is to be treated as 'confirmed' in accordance with the terms of the underlying agreement. + +Support +------- +The Support Service is provided to Participants and Business Network Operators to manage / resolve inquiries and incidents +relating to the Doorman, Network Map Service and Notary Service, and any other relevant services. diff --git a/docs/source/corda-network/joining-corda-network.md b/docs/source/corda-network/joining-corda-network.md new file mode 100644 index 0000000000..43aff317fd --- /dev/null +++ b/docs/source/corda-network/joining-corda-network.md @@ -0,0 +1,36 @@ +Joining Corda Network +===================== + +Corda Network participation requires each node to possess a recognised Certificate Authority (CA) signed certificate +(“Participation Certificate”), which is used to derive other digital certificates required (such as legal entity signing +certificates and TLS certificates). + +Identity certificates must be issued by the Corda Network Operator (Doorman / Network Map), which guarantees that the identity +listed on the certificate is uniquely held by a single party within the network. + +A high-level outline of steps to join the Network is listed below. This assumes that Participants wish to operate a node +and already have access to at least one CorDapp which they wish to deploy. A more detailed step-by-step guide will soon +be available. + +1. Obtain Corda software - either the Enterprise version, via a Corda sales representative, or the open source version +through [github](https://github.com/corda). +2. For the time being, request the trust root certificate from Corda Network Doorman, by emailing doorman@r3.com, which +will be sent back as a truststore.jks file. In future, the Corda Network trust root will be packaged in the software +distribution. +3. [Start the node](https://docs.corda.net/deploying-a-node.html) - where applicable, with help from a Corda +representative. +4. [Configure the node](https://docs.corda.net/corda-configuration-file.html) – a node.conf file must be included in the +root directory of every Corda node. This includes: specifying an email address in relation to the certificate signing +request as well as choosing a distinguished name. +5. Run the initial registration. This will send a Certificate Signing Request (with the relevant name and email) to the +Network Manager service (Doorman / Network Map). +6. Sign Participant terms of use, either directly or indirectly: +* **Sponsored model**: A Business Network Operator (BNO) requesting approval for a certificate on behalf of the Participant. +* **Direct model**: The Participant requesting a certificate for themselves. +7. Doorman verification checks – a number of identity-related checks will be conducted, before issuing a certificate, +including email and legal entity checks. +8. Once identity checks have been completed, a signed CA certificate will be released by the Doorman to the +node. +9. Completion - the node will then sign its node IP address and submit it to the Network Map, for broadcast to other +Participant nodes. + diff --git a/docs/source/index.rst b/docs/source/index.rst index 7a6e227b95..b34e467378 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -99,3 +99,12 @@ application development please continue to refer to `the main project documentat corda-networks-index.rst certificate-revocation +.. conditional-toctree:: + :caption: Corda Network + :maxdepth: 2 + :if_tag: htmlmode + + corda-network/index.md + corda-network/governance-structure.md + corda-network/governance-guidelines.md + corda-network/joining-corda-network.md \ No newline at end of file diff --git a/node/src/main/kotlin/net/corda/node/serialization/kryo/DefaultKryoCustomizer.kt b/node/src/main/kotlin/net/corda/node/serialization/kryo/DefaultKryoCustomizer.kt index 37bd1acd33..3ca151ea8c 100644 --- a/node/src/main/kotlin/net/corda/node/serialization/kryo/DefaultKryoCustomizer.kt +++ b/node/src/main/kotlin/net/corda/node/serialization/kryo/DefaultKryoCustomizer.kt @@ -18,6 +18,7 @@ import net.corda.core.crypto.CompositeKey import net.corda.core.crypto.SecureHash import net.corda.core.identity.PartyAndCertificate import net.corda.core.internal.AbstractAttachment +import net.corda.core.internal.LazyMappedList import net.corda.core.internal.readFully import net.corda.core.serialization.MissingAttachmentsException import net.corda.core.serialization.SerializationWhitelist @@ -82,6 +83,7 @@ object DefaultKryoCustomizer { // TODO: re-organise registrations into logical groups before v1.0 register(Arrays.asList("").javaClass, ArraysAsListSerializer()) + register(LazyMappedList::class.java, LazyMappedListSerializer) register(SignedTransaction::class.java, SignedTransactionSerializer) register(WireTransaction::class.java, WireTransactionSerializer) register(SerializedBytes::class.java, SerializedBytesSerializer) diff --git a/node/src/main/kotlin/net/corda/node/serialization/kryo/Kryo.kt b/node/src/main/kotlin/net/corda/node/serialization/kryo/Kryo.kt index c2a37d5b9c..0384a6cc56 100644 --- a/node/src/main/kotlin/net/corda/node/serialization/kryo/Kryo.kt +++ b/node/src/main/kotlin/net/corda/node/serialization/kryo/Kryo.kt @@ -12,8 +12,8 @@ import net.corda.core.contracts.PrivacySalt import net.corda.core.crypto.Crypto import net.corda.core.crypto.SecureHash import net.corda.core.crypto.TransactionSignature +import net.corda.core.internal.LazyMappedList import net.corda.core.internal.uncheckedCast -import net.corda.core.serialization.SerializationContext import net.corda.core.serialization.SerializeAsTokenContext import net.corda.core.serialization.SerializedBytes import net.corda.core.transactions.* @@ -491,3 +491,11 @@ class ThrowableSerializer(kryo: Kryo, type: Class) : Serializer private fun Throwable.setSuppressedToSentinel() = suppressedField.set(this, sentinelValue) } + +/** For serializing the utility [LazyMappedList]. It will serialize the fully resolved object.*/ +@ThreadSafe +@SuppressWarnings("ALL") +object LazyMappedListSerializer : Serializer>() { + override fun write(kryo: Kryo, output: Output, obj: List<*>) = kryo.writeClassAndObject(output, obj.toList()) + override fun read(kryo: Kryo, input: Input, type: Class>) = kryo.readClassAndObject(input) as List<*> +} diff --git a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt index 60fa089ff4..21c8fb5507 100644 --- a/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt +++ b/tools/cliutils/src/main/kotlin/net/corda/cliutils/CordaCliWrapper.kt @@ -97,7 +97,7 @@ fun CordaCliWrapper.start(args: Array) { exitProcess(ExitCodes.SUCCESS) } catch (e: ExecutionException) { val throwable = e.cause ?: e - if (this.verbose) { + if (this.verbose || this.subCommands().any { it.verbose} ) { throwable.printStackTrace() } else { System.err.println("*ERROR*: ${throwable.rootMessage ?: "Use --verbose for more details"}")