mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +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>
|
||||
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 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 {
|
||||
/** 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) */
|
||||
override val deposit: PartyAndReference
|
||||
val deposit: PartyAndReference
|
||||
override val amount: Amount<Issued<T>>
|
||||
/** There must be a MoveCommand signed by this key to claim the amount */
|
||||
override val owner: PublicKey
|
||||
|
@ -1,16 +1,15 @@
|
||||
package com.r3corda.contracts.cash
|
||||
|
||||
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.OwnableState
|
||||
import java.security.PublicKey
|
||||
|
||||
/**
|
||||
* Common elements of cash contract states.
|
||||
*/
|
||||
interface FungibleAssetState<T> : OwnableState {
|
||||
val issuanceDef: Issued<T>
|
||||
/** Where the underlying currency backing this ledger entry can be found (propagated) */
|
||||
val deposit: PartyAndReference
|
||||
interface FungibleAssetState<T, I> : OwnableState {
|
||||
val issuanceDef: I
|
||||
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)
|
||||
|
||||
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 /////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -399,3 +399,24 @@ fun calculateDaysBetween(startDate: LocalDate,
|
||||
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
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* 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. */
|
||||
// TODO: Revisit use of nonce values - should this be part of the TX rather than the command perhaps?
|
||||
interface IssueCommand : CommandData {
|
||||
val nonce: Long
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user