mirror of
https://github.com/corda/corda.git
synced 2025-05-05 02:03:06 +00:00
Add netting support structures
Add NetType enum for use in contracts which deal with netting Add BilateralNettingState interface Add support for more complex issued things
This commit is contained in:
parent
7ee6bd05ce
commit
d24ec06b40
@ -62,6 +62,9 @@ class Cash : FungibleAsset<Currency>() {
|
|||||||
override val participants: List<PublicKey>
|
override val participants: List<PublicKey>
|
||||||
get() = listOf(owner)
|
get() = listOf(owner)
|
||||||
|
|
||||||
|
override fun move(amount: Amount<Issued<Currency>>, owner: PublicKey): FungibleAsset.State<Currency>
|
||||||
|
= copy(amount = amount, owner = owner)
|
||||||
|
|
||||||
override fun toString() = "${Emoji.bagOfCash}Cash($amount at $deposit owned by ${owner.toStringShort()})"
|
override fun toString() = "${Emoji.bagOfCash}Cash($amount at $deposit owned by ${owner.toStringShort()})"
|
||||||
|
|
||||||
override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
|
||||||
|
@ -31,9 +31,9 @@ class InsufficientBalanceException(val amountMissing: Amount<Currency>) : Except
|
|||||||
*/
|
*/
|
||||||
abstract class FungibleAsset<T> : Contract {
|
abstract class FungibleAsset<T> : Contract {
|
||||||
/** A state representing a cash claim against some party */
|
/** A state representing a cash claim against some party */
|
||||||
interface State<T> : FungibleAssetState<T> {
|
interface State<T> : FungibleAssetState<T, Issued<T>> {
|
||||||
/** Where the underlying currency backing this ledger entry can be found (propagated) */
|
/** Where the underlying currency backing this ledger entry can be found (propagated) */
|
||||||
override val deposit: PartyAndReference
|
val deposit: PartyAndReference
|
||||||
override val amount: Amount<Issued<T>>
|
override val amount: Amount<Issued<T>>
|
||||||
/** There must be a MoveCommand signed by this key to claim the amount */
|
/** There must be a MoveCommand signed by this key to claim the amount */
|
||||||
override val owner: PublicKey
|
override val owner: PublicKey
|
||||||
|
@ -1,16 +1,15 @@
|
|||||||
package com.r3corda.contracts.cash
|
package com.r3corda.contracts.cash
|
||||||
|
|
||||||
import com.r3corda.core.contracts.Amount
|
import com.r3corda.core.contracts.Amount
|
||||||
import com.r3corda.core.contracts.OwnableState
|
|
||||||
import com.r3corda.core.contracts.PartyAndReference
|
|
||||||
import com.r3corda.core.contracts.Issued
|
import com.r3corda.core.contracts.Issued
|
||||||
|
import com.r3corda.core.contracts.OwnableState
|
||||||
|
import java.security.PublicKey
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Common elements of cash contract states.
|
* Common elements of cash contract states.
|
||||||
*/
|
*/
|
||||||
interface FungibleAssetState<T> : OwnableState {
|
interface FungibleAssetState<T, I> : OwnableState {
|
||||||
val issuanceDef: Issued<T>
|
val issuanceDef: I
|
||||||
/** Where the underlying currency backing this ledger entry can be found (propagated) */
|
|
||||||
val deposit: PartyAndReference
|
|
||||||
val amount: Amount<Issued<T>>
|
val amount: Amount<Issued<T>>
|
||||||
|
fun move(amount: Amount<Issued<T>>, owner: PublicKey): FungibleAssetState<T, I>
|
||||||
}
|
}
|
@ -30,7 +30,7 @@ val Int.SWISS_FRANCS: Amount<Currency> get() = Amount(this.toLong() * 100, CHF)
|
|||||||
val Double.DOLLARS: Amount<Currency> get() = Amount((this * 100).toLong(), USD)
|
val Double.DOLLARS: Amount<Currency> get() = Amount((this * 100).toLong(), USD)
|
||||||
|
|
||||||
infix fun Currency.`issued by`(deposit: PartyAndReference) : Issued<Currency> = Issued<Currency>(deposit, this)
|
infix fun Currency.`issued by`(deposit: PartyAndReference) : Issued<Currency> = Issued<Currency>(deposit, this)
|
||||||
infix fun Amount<Currency>.`issued by`(deposit: PartyAndReference) : Amount<Issued<Currency>> = Amount(quantity, token `issued by` deposit)
|
infix fun <T> Amount<T>.`issued by`(deposit: PartyAndReference) : Amount<Issued<T>> = Amount(quantity, Issued<T>(deposit, this.token))
|
||||||
|
|
||||||
//// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
|
//// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -399,3 +399,24 @@ fun calculateDaysBetween(startDate: LocalDate,
|
|||||||
else -> TODO("Can't calculate days using convention $dcbDay / $dcbYear")
|
else -> TODO("Can't calculate days using convention $dcbDay / $dcbYear")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum for the types of netting that can be applied to state objects. Exact behaviour
|
||||||
|
* for each type of netting is left to the contract to determine.
|
||||||
|
*/
|
||||||
|
enum class NetType {
|
||||||
|
/**
|
||||||
|
* Close-out netting applies where one party is bankrupt or otherwise defaults (exact terms are contract specific),
|
||||||
|
* and allows their counterparty to net obligations without requiring approval from all parties. For example, if
|
||||||
|
* Bank A owes Bank B £1m, and Bank B owes Bank A £1m, in the case of Bank B defaulting this would enable Bank A
|
||||||
|
* to net out the two obligations to zero, rather than being legally obliged to pay £1m without any realistic
|
||||||
|
* expectation of the debt to them being paid. Realistically this is limited to bilateral netting, to simplify
|
||||||
|
* determining which party must sign the netting transaction.
|
||||||
|
*/
|
||||||
|
CLOSE_OUT,
|
||||||
|
/**
|
||||||
|
* "Payment" is used to refer to conventional netting, where all parties must confirm the netting transaction. This
|
||||||
|
* can be a multilateral netting transaction, and may be created by a central clearing service.
|
||||||
|
*/
|
||||||
|
PAYMENT
|
||||||
|
}
|
@ -18,6 +18,23 @@ interface NamedByHash {
|
|||||||
val id: SecureHash
|
val id: SecureHash
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for state objects that support being netted with other state objects.
|
||||||
|
*/
|
||||||
|
interface BilateralNettableState<T: BilateralNettableState<T>> {
|
||||||
|
/**
|
||||||
|
* Returns an object used to determine if two states can be subject to close-out netting. If two states return
|
||||||
|
* equal objects, they can be close out netted together.
|
||||||
|
*/
|
||||||
|
val bilateralNetState: Any
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Perform bilateral netting of this state with another state. The two states must be compatible (as in
|
||||||
|
* bilateralNetState objects are equal).
|
||||||
|
*/
|
||||||
|
fun net(other: T): T
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk
|
* A contract state (or just "state") contains opaque data used by a contract program. It can be thought of as a disk
|
||||||
* file that the program can use to persist data across transactions. States are immutable: once created they are never
|
* file that the program can use to persist data across transactions. States are immutable: once created they are never
|
||||||
@ -233,6 +250,7 @@ data class Command(val value: CommandData, val signers: List<PublicKey>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** A common issue command, to enforce that issue commands have a nonce value. */
|
/** A common issue command, to enforce that issue commands have a nonce value. */
|
||||||
|
// TODO: Revisit use of nonce values - should this be part of the TX rather than the command perhaps?
|
||||||
interface IssueCommand : CommandData {
|
interface IssueCommand : CommandData {
|
||||||
val nonce: Long
|
val nonce: Long
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user