Hibernate ORM implementation for states.

This commit is contained in:
rick.parker
2016-09-27 15:17:27 +01:00
parent 07e528c659
commit ec975b0426
19 changed files with 540 additions and 31 deletions

View File

@ -6,13 +6,21 @@ import com.r3corda.contracts.asset.InsufficientBalanceException
import com.r3corda.contracts.asset.sumCashBy
import com.r3corda.contracts.clause.AbstractIssue
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.*
import com.r3corda.core.contracts.clauses.AnyComposition
import com.r3corda.core.contracts.clauses.Clause
import com.r3corda.core.contracts.clauses.GroupClauseVerifier
import com.r3corda.core.contracts.clauses.verifyClause
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.toBase58String
import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.random63BitValue
import com.r3corda.core.schemas.MappedSchema
import com.r3corda.core.schemas.PersistentState
import com.r3corda.core.schemas.QueryableState
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.utilities.Emoji
import com.r3corda.schemas.CommercialPaperSchemaV1
import java.security.PublicKey
import java.time.Instant
import java.util.*
@ -58,7 +66,7 @@ class CommercialPaper : Contract {
override val owner: PublicKey,
val faceValue: Amount<Issued<Currency>>,
val maturityDate: Instant
) : OwnableState, ICommercialPaperState {
) : OwnableState, QueryableState, ICommercialPaperState {
override val contract = CP_PROGRAM_ID
override val participants: List<PublicKey>
get() = listOf(owner)
@ -75,6 +83,26 @@ class CommercialPaper : Contract {
override fun withIssuance(newIssuance: PartyAndReference): ICommercialPaperState = copy(issuance = newIssuance)
override fun withFaceValue(newFaceValue: Amount<Issued<Currency>>): ICommercialPaperState = copy(faceValue = newFaceValue)
override fun withMaturityDate(newMaturityDate: Instant): ICommercialPaperState = copy(maturityDate = newMaturityDate)
/** Object Relational Mapping support. */
override fun supportedSchemas(): Iterable<MappedSchema> = listOf(CommercialPaperSchemaV1)
/** Object Relational Mapping support. */
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommericalPaperState(
issuanceParty = this.issuance.party.owningKey.toBase58String(),
issuanceRef = this.issuance.reference.bits,
owner = this.owner.toBase58String(),
maturity = this.maturityDate,
faceValue = this.faceValue.quantity,
currency = this.faceValue.token.product.currencyCode,
faceValueIssuerParty = this.faceValue.token.issuer.party.owningKey.toBase58String(),
faceValueIssuerRef = this.faceValue.token.issuer.reference.bits
)
else -> throw IllegalArgumentException("Unrecognised schema $schema")
}
}
}
interface Clauses {

View File

@ -4,11 +4,18 @@ import com.r3corda.contracts.clause.AbstractConserveAmount
import com.r3corda.contracts.clause.AbstractIssue
import com.r3corda.contracts.clause.NoZeroSizedOutputs
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.*
import com.r3corda.core.contracts.clauses.AllComposition
import com.r3corda.core.contracts.clauses.FirstComposition
import com.r3corda.core.contracts.clauses.GroupClauseVerifier
import com.r3corda.core.contracts.clauses.verifyClause
import com.r3corda.core.crypto.*
import com.r3corda.core.node.services.Vault
import com.r3corda.core.schemas.MappedSchema
import com.r3corda.core.schemas.PersistentState
import com.r3corda.core.schemas.QueryableState
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.utilities.Emoji
import com.r3corda.schemas.CashSchemaV1
import java.math.BigInteger
import java.security.PublicKey
import java.util.*
@ -79,7 +86,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
/** There must be a MoveCommand signed by this key to claim the amount. */
override val owner: PublicKey,
override val encumbrance: Int? = null
) : FungibleAsset<Currency> {
) : FungibleAsset<Currency>, QueryableState {
constructor(deposit: PartyAndReference, amount: Amount<Currency>, owner: PublicKey)
: this(Amount(amount.quantity, Issued(deposit, amount.token)), owner)
@ -95,6 +102,24 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
override fun toString() = "${Emoji.bagOfCash}Cash($amount at $deposit owned by ${owner.toStringShort()})"
override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
/** Object Relational Mapping support. */
override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) {
is CashSchemaV1 -> CashSchemaV1.PersistentCashState(
encumbrance = this.encumbrance,
owner = this.owner.toBase58String(),
pennies = this.amount.quantity,
currency = this.amount.token.product.currencyCode,
issuerParty = this.amount.token.issuer.party.owningKey.toBase58String(),
issuerRef = this.amount.token.issuer.reference.bits
)
else -> throw IllegalArgumentException("Unrecognised schema $schema")
}
}
/** Object Relational Mapping support. */
override fun supportedSchemas(): Iterable<MappedSchema> = listOf(CashSchemaV1)
}
// Just for grouping

View File

@ -0,0 +1,40 @@
package com.r3corda.schemas
import com.r3corda.core.schemas.MappedSchema
import com.r3corda.core.schemas.PersistentState
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table
/**
* An object used to fully qualify the [CashSchema] family name (i.e. independent of version).
*/
object CashSchema
/**
* First version of a cash contract ORM schema that maps all fields of the [Cash] contract state as it stood
* at the time of writing.
*/
object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCashState::class.java)) {
@Entity
@Table(name = "cash_states")
class PersistentCashState(
@Column(name = "encumbrance")
var encumbrance: Int?,
@Column(name = "owner_key")
var owner: String,
@Column(name = "pennies")
var pennies: Long,
@Column(name = "ccy_code", length = 3)
var currency: String,
@Column(name = "issuer_key")
var issuerParty: String,
@Column(name = "issuer_ref")
var issuerRef: ByteArray
) : PersistentState()
}

View File

@ -0,0 +1,47 @@
package com.r3corda.schemas
import com.r3corda.core.schemas.MappedSchema
import com.r3corda.core.schemas.PersistentState
import java.time.Instant
import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.Table
/**
* An object used to fully qualify the [CommercialPaperSchema] family name (i.e. independent of version).
*/
object CommercialPaperSchema
/**
* First version of a commercial paper contract ORM schema that maps all fields of the [CommercialPaper] contract state
* as it stood at the time of writing.
*/
object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSchema.javaClass, version = 1, mappedTypes = listOf(PersistentCommericalPaperState::class.java)) {
@Entity
@Table(name = "cp_states")
class PersistentCommericalPaperState(
@Column(name = "issuance_key")
var issuanceParty: String,
@Column(name = "issuance_ref")
var issuanceRef: ByteArray,
@Column(name = "owner_key")
var owner: String,
@Column(name = "maturity_instant")
var maturity: Instant,
@Column(name = "face_value")
var faceValue: Long,
@Column(name = "ccy_code", length = 3)
var currency: String,
@Column(name = "face_value_issuer_key")
var faceValueIssuerParty: String,
@Column(name = "face_value_issuer_ref")
var faceValueIssuerRef: ByteArray
) : PersistentState()
}