Standardisation of Public Keys in Schema entities. (#68)

* Standardisation in usage of Public Keys in Schema entities.
Use PK Hash where optimal, otherwise use ByteArray/LOB representation of PK.

* Redundant after rebase.

* Use .encoded and Crypto.decode<Public|Private>Key(bytes) instead of Corda serialization.

* Optimize DBPartyAndCertificate entity to store and query on ownerKeyHash.
This commit is contained in:
josecoll 2017-10-20 09:40:21 +01:00 committed by GitHub
parent e6ce42281f
commit def9d9d0ea
20 changed files with 91 additions and 77 deletions

View File

@ -1,11 +1,13 @@
package net.corda.core.schemas package net.corda.core.schemas
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.node.NodeInfo import net.corda.core.node.NodeInfo
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.core.utilities.toBase58String
import java.io.Serializable import java.io.Serializable
import javax.persistence.* import javax.persistence.*
@ -88,20 +90,24 @@ object NodeInfoSchemaV1 : MappedSchema(
@Column(name = "party_name", nullable = false) @Column(name = "party_name", nullable = false)
val name: String, val name: String,
@Column(name = "owning_key", length = 65535, nullable = false)
val owningKey: String,
@Column(name = "party_cert_binary")
@Lob @Lob
@Column(name = "owning_key_hash", length = MAX_HASH_HEX_SIZE)
val owningKeyHash: String,
@Lob
@Column(name = "party_cert_binary")
val partyCertBinary: ByteArray, val partyCertBinary: ByteArray,
val isMain: Boolean, val isMain: Boolean,
@ManyToMany(mappedBy = "legalIdentitiesAndCerts", cascade = arrayOf(CascadeType.ALL)) // ManyToMany because of distributed services. @ManyToMany(mappedBy = "legalIdentitiesAndCerts", cascade = arrayOf(CascadeType.ALL)) // ManyToMany because of distributed services.
private val persistentNodeInfos: Set<PersistentNodeInfo> = emptySet() private val persistentNodeInfos: Set<PersistentNodeInfo> = emptySet()
) { ) {
constructor(partyAndCert: PartyAndCertificate, isMain: Boolean = false) constructor(partyAndCert: PartyAndCertificate, isMain: Boolean = false)
: this(partyAndCert.party.name.toString(), partyAndCert.party.owningKey.toBase58String(), partyAndCert.serialize().bytes, isMain) : this(partyAndCert.party.name.toString(),
partyAndCert.party.owningKey.toStringShort(),
partyAndCert.serialize(context = SerializationDefaults.STORAGE_CONTEXT).bytes, isMain)
fun toLegalIdentityAndCert(): PartyAndCertificate { fun toLegalIdentityAndCert(): PartyAndCertificate {
return partyCertBinary.deserialize() return partyCertBinary.deserialize()

View File

@ -12,6 +12,14 @@ import javax.xml.bind.DatatypeConverter
// This file includes useful encoding methods and extension functions for the most common encoding/decoding operations. // This file includes useful encoding methods and extension functions for the most common encoding/decoding operations.
/**
* The maximum supported field-size for hash HEX-encoded outputs (e.g. database fields).
* This value is enough to support hash functions with outputs up to 512 bits (e.g. SHA3-512), in which
* case 128 HEX characters are required.
* 130 was selected instead of 128, to allow for 2 extra characters that will be used as hash-scheme identifiers.
*/
const val MAX_HASH_HEX_SIZE = 130
// [ByteArray] encoders // [ByteArray] encoders
/** Convert a byte array to a Base58 encoded [String]. */ /** Convert a byte array to a Base58 encoded [String]. */

View File

@ -3,7 +3,7 @@ package net.corda.finance.contracts
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.crypto.NullKeys.NULL_PARTY import net.corda.core.crypto.NullKeys.NULL_PARTY
import net.corda.core.utilities.toBase58String import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
@ -76,13 +76,13 @@ class CommercialPaper : Contract {
override fun generateMappedObject(schema: MappedSchema): PersistentState { override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) { return when (schema) {
is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommercialPaperState( is CommercialPaperSchemaV1 -> CommercialPaperSchemaV1.PersistentCommercialPaperState(
issuanceParty = this.issuance.party.owningKey.toBase58String(), issuancePartyHash = this.issuance.party.owningKey.toStringShort(),
issuanceRef = this.issuance.reference.bytes, issuanceRef = this.issuance.reference.bytes,
owner = this.owner.owningKey.toBase58String(), ownerHash = this.owner.owningKey.toStringShort(),
maturity = this.maturityDate, maturity = this.maturityDate,
faceValue = this.faceValue.quantity, faceValue = this.faceValue.quantity,
currency = this.faceValue.token.product.currencyCode, currency = this.faceValue.token.product.currencyCode,
faceValueIssuerParty = this.faceValue.token.issuer.party.owningKey.toBase58String(), faceValueIssuerPartyHash = this.faceValue.token.issuer.party.owningKey.toStringShort(),
faceValueIssuerRef = this.faceValue.token.issuer.reference.bytes faceValueIssuerRef = this.faceValue.token.issuer.reference.bytes
) )
/** Additional schema mappings would be added here (eg. CommercialPaperV2, ...) */ /** Additional schema mappings would be added here (eg. CommercialPaperV2, ...) */

View File

@ -8,6 +8,7 @@ import net.corda.core.contracts.*
import net.corda.core.contracts.Amount.Companion.sumOrThrow import net.corda.core.contracts.Amount.Companion.sumOrThrow
import net.corda.core.crypto.NullKeys.NULL_PARTY import net.corda.core.crypto.NullKeys.NULL_PARTY
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
@ -19,7 +20,6 @@ import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState import net.corda.core.schemas.QueryableState
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.toBase58String
import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection
import net.corda.finance.schemas.CashSchemaV1 import net.corda.finance.schemas.CashSchemaV1
import net.corda.finance.utils.sumCash import net.corda.finance.utils.sumCash
@ -83,7 +83,7 @@ class Cash : OnLedgerAsset<Currency, Cash.Commands, Cash.State>() {
owner = this.owner, owner = this.owner,
pennies = this.amount.quantity, pennies = this.amount.quantity,
currency = this.amount.token.product.currencyCode, currency = this.amount.token.product.currencyCode,
issuerParty = this.amount.token.issuer.party.owningKey.toBase58String(), issuerPartyHash = this.amount.token.issuer.party.owningKey.toStringShort(),
issuerRef = this.amount.token.issuer.reference.bytes issuerRef = this.amount.token.issuer.reference.bytes
) )
/** Additional schema mappings would be added here (eg. CashSchemaV2, CashSchemaV3, ...) */ /** Additional schema mappings would be added here (eg. CashSchemaV2, CashSchemaV3, ...) */

View File

@ -1,6 +1,7 @@
package net.corda.finance.contracts.asset.cash.selection package net.corda.finance.contracts.asset.cash.selection
import net.corda.core.contracts.Amount import net.corda.core.contracts.Amount
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.utilities.* import net.corda.core.utilities.*
@ -44,7 +45,7 @@ class CashSelectionH2Impl : AbstractCashSelection() {
(if (notary != null) (if (notary != null)
" AND vs.notary_name = ?" else "") + " AND vs.notary_name = ?" else "") +
(if (onlyFromIssuerParties.isNotEmpty()) (if (onlyFromIssuerParties.isNotEmpty())
" AND ccs.issuer_key IN (?)" else "") + " AND ccs.issuer_key_hash IN (?)" else "") +
(if (withIssuerRefs.isNotEmpty()) (if (withIssuerRefs.isNotEmpty())
" AND ccs.issuer_ref IN (?)" else "") " AND ccs.issuer_ref IN (?)" else "")
@ -57,7 +58,7 @@ class CashSelectionH2Impl : AbstractCashSelection() {
if (notary != null) if (notary != null)
psSelectJoin.setString(++pIndex, notary.name.toString()) psSelectJoin.setString(++pIndex, notary.name.toString())
if (onlyFromIssuerParties.isNotEmpty()) if (onlyFromIssuerParties.isNotEmpty())
psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toBase58String() as Any}.toTypedArray() ) psSelectJoin.setObject(++pIndex, onlyFromIssuerParties.map { it.owningKey.toStringShort() as Any}.toTypedArray() )
if (withIssuerRefs.isNotEmpty()) if (withIssuerRefs.isNotEmpty())
psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes.toHexString() as Any }.toTypedArray()) psSelectJoin.setObject(++pIndex, withIssuerRefs.map { it.bytes.toHexString() as Any }.toTypedArray())
log.debug { psSelectJoin.toString() } log.debug { psSelectJoin.toString() }

View File

@ -4,10 +4,8 @@ import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import javax.persistence.Column import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import javax.persistence.Entity import javax.persistence.*
import javax.persistence.Index
import javax.persistence.Table
/** /**
* An object used to fully qualify the [CashSchema] family name (i.e. independent of version). * An object used to fully qualify the [CashSchema] family name (i.e. independent of version).
@ -35,8 +33,9 @@ object CashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, version
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@Column(name = "issuer_key") @Lob
var issuerParty: String, @Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var issuerPartyHash: String,
@Column(name = "issuer_ref") @Column(name = "issuer_ref")
var issuerRef: ByteArray var issuerRef: ByteArray

View File

@ -3,6 +3,7 @@ package net.corda.finance.schemas
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import java.time.Instant import java.time.Instant
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity
@ -26,14 +27,14 @@ object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSche
Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value"))) Index(name = "face_value_index", columnList = "face_value")))
class PersistentCommercialPaperState( class PersistentCommercialPaperState(
@Column(name = "issuance_key") @Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE)
var issuanceParty: String, var issuancePartyHash: String,
@Column(name = "issuance_ref") @Column(name = "issuance_ref")
var issuanceRef: ByteArray, var issuanceRef: ByteArray,
@Column(name = "owner_key") @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)
var owner: String, var ownerHash: String,
@Column(name = "maturity_instant") @Column(name = "maturity_instant")
var maturity: Instant, var maturity: Instant,
@ -44,8 +45,8 @@ object CommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPaperSche
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key") @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var faceValueIssuerParty: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref") @Column(name = "face_value_issuer_ref")
var faceValueIssuerRef: ByteArray var faceValueIssuerRef: ByteArray

View File

@ -1,19 +1,19 @@
package net.corda.finance.contracts.asset package net.corda.finance.contracts.asset
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.utilities.toBase58String import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.internal.Emoji import net.corda.core.internal.Emoji
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.schemas.QueryableState import net.corda.core.schemas.QueryableState
import net.corda.core.transactions.LedgerTransaction import net.corda.core.transactions.LedgerTransaction
import net.corda.finance.utils.sumCash
import net.corda.finance.utils.sumCashOrNull
import net.corda.finance.utils.sumCashOrZero
import net.corda.finance.schemas.SampleCashSchemaV1 import net.corda.finance.schemas.SampleCashSchemaV1
import net.corda.finance.schemas.SampleCashSchemaV2 import net.corda.finance.schemas.SampleCashSchemaV2
import net.corda.finance.schemas.SampleCashSchemaV3 import net.corda.finance.schemas.SampleCashSchemaV3
import net.corda.finance.utils.sumCash
import net.corda.finance.utils.sumCashOrNull
import net.corda.finance.utils.sumCashOrZero
import java.security.PublicKey import java.security.PublicKey
import java.util.* import java.util.*
@ -43,10 +43,10 @@ class DummyFungibleContract : OnLedgerAsset<Currency, DummyFungibleContract.Comm
override fun generateMappedObject(schema: MappedSchema): PersistentState { override fun generateMappedObject(schema: MappedSchema): PersistentState {
return when (schema) { return when (schema) {
is SampleCashSchemaV1 -> SampleCashSchemaV1.PersistentCashState( is SampleCashSchemaV1 -> SampleCashSchemaV1.PersistentCashState(
owner = this.owner.owningKey.toBase58String(), ownerHash = this.owner.owningKey.toStringShort(),
pennies = this.amount.quantity, pennies = this.amount.quantity,
currency = this.amount.token.product.currencyCode, currency = this.amount.token.product.currencyCode,
issuerParty = this.amount.token.issuer.party.owningKey.toBase58String(), issuerPartyHash = this.amount.token.issuer.party.owningKey.toStringShort(),
issuerRef = this.amount.token.issuer.reference.bytes issuerRef = this.amount.token.issuer.reference.bytes
) )
is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState( is SampleCashSchemaV2 -> SampleCashSchemaV2.PersistentCashState(

View File

@ -2,6 +2,7 @@ package net.corda.finance.schemas
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity
import javax.persistence.Index import javax.persistence.Index
@ -22,8 +23,8 @@ object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"), indexes = arrayOf(Index(name = "ccy_code_idx", columnList = "ccy_code"),
Index(name = "pennies_idx", columnList = "pennies"))) Index(name = "pennies_idx", columnList = "pennies")))
class PersistentCashState( class PersistentCashState(
@Column(name = "owner_key") @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)
var owner: String, var ownerHash: String,
@Column(name = "pennies") @Column(name = "pennies")
var pennies: Long, var pennies: Long,
@ -31,8 +32,8 @@ object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@Column(name = "issuer_key") @Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var issuerParty: String, var issuerPartyHash: String,
@Column(name = "issuer_ref") @Column(name = "issuer_ref")
var issuerRef: ByteArray var issuerRef: ByteArray

View File

@ -2,6 +2,7 @@ package net.corda.finance.schemas
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.schemas.PersistentState import net.corda.core.schemas.PersistentState
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import java.time.Instant import java.time.Instant
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity
@ -24,14 +25,14 @@ object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPap
Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "maturity_index", columnList = "maturity_instant"),
Index(name = "face_value_index", columnList = "face_value"))) Index(name = "face_value_index", columnList = "face_value")))
class PersistentCommercialPaperState( class PersistentCommercialPaperState(
@Column(name = "issuance_key") @Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE)
var issuanceParty: String, var issuancePartyHash: String,
@Column(name = "issuance_ref") @Column(name = "issuance_ref")
var issuanceRef: ByteArray, var issuanceRef: ByteArray,
@Column(name = "owner_key") @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE)
var owner: String, var ownerHash: String,
@Column(name = "maturity_instant") @Column(name = "maturity_instant")
var maturity: Instant, var maturity: Instant,
@ -42,8 +43,8 @@ object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPap
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key") @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var faceValueIssuerParty: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref") @Column(name = "face_value_issuer_ref")
var faceValueIssuerRef: ByteArray var faceValueIssuerRef: ByteArray

View File

@ -3,6 +3,7 @@ package net.corda.finance.schemas
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.schemas.CommonSchemaV1 import net.corda.core.schemas.CommonSchemaV1
import net.corda.core.schemas.MappedSchema import net.corda.core.schemas.MappedSchema
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import java.time.Instant import java.time.Instant
import javax.persistence.Column import javax.persistence.Column
import javax.persistence.Entity import javax.persistence.Entity
@ -26,8 +27,8 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key") @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE)
var faceValueIssuerParty: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref") @Column(name = "face_value_issuer_ref")
var faceValueIssuerRef: ByteArray, var faceValueIssuerRef: ByteArray,

View File

@ -11,8 +11,8 @@ import net.corda.core.node.services.UnknownAnonymousPartyException
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.utilities.debug import net.corda.core.utilities.debug
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.NODE_DATABASE_PREFIX
import org.bouncycastle.cert.X509CertificateHolder import org.bouncycastle.cert.X509CertificateHolder
import java.io.ByteArrayInputStream import java.io.ByteArrayInputStream

View File

@ -8,8 +8,8 @@ import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.NODE_DATABASE_PREFIX
import org.bouncycastle.operator.ContentSigner import org.bouncycastle.operator.ContentSigner
import java.security.KeyPair import java.security.KeyPair
@ -46,17 +46,14 @@ class PersistentKeyManagementService(val identityService: IdentityService,
var privateKey: ByteArray = ByteArray(0) var privateKey: ByteArray = ByteArray(0)
) { ) {
constructor(publicKey: PublicKey, privateKey: PrivateKey) constructor(publicKey: PublicKey, privateKey: PrivateKey)
: this(publicKey.toStringShort(), : this(publicKey.toStringShort(), publicKey.encoded, privateKey.encoded)
publicKey.serialize(context = SerializationDefaults.STORAGE_CONTEXT).bytes,
privateKey.serialize(context = SerializationDefaults.STORAGE_CONTEXT).bytes)
} }
private companion object { private companion object {
fun createKeyMap(): AppendOnlyPersistentMap<PublicKey, PrivateKey, PersistentKey, String> { fun createKeyMap(): AppendOnlyPersistentMap<PublicKey, PrivateKey, PersistentKey, String> {
return AppendOnlyPersistentMap( return AppendOnlyPersistentMap(
toPersistentEntityKey = { it.toStringShort() }, toPersistentEntityKey = { it.toStringShort() },
fromPersistentEntity = { Pair(it.publicKey.deserialize(context = SerializationDefaults.STORAGE_CONTEXT), fromPersistentEntity = { Pair(Crypto.decodePublicKey(it.publicKey), Crypto.decodePrivateKey(it.privateKey)) },
it.privateKey.deserialize(context = SerializationDefaults.STORAGE_CONTEXT)) },
toPersistentEntity = { key: PublicKey, value: PrivateKey -> toPersistentEntity = { key: PublicKey, value: PrivateKey ->
PersistentKey(key, value) PersistentKey(key, value)
}, },

View File

@ -2,6 +2,7 @@ package net.corda.node.services.network
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.AbstractParty import net.corda.core.identity.AbstractParty
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
@ -17,6 +18,7 @@ import net.corda.core.node.services.NetworkMapCache.MapChange
import net.corda.core.node.services.NotaryService import net.corda.core.node.services.NotaryService
import net.corda.core.node.services.PartyInfo import net.corda.core.node.services.PartyInfo
import net.corda.core.schemas.NodeInfoSchemaV1 import net.corda.core.schemas.NodeInfoSchemaV1
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
@ -311,9 +313,9 @@ open class PersistentNetworkMapCache(private val serviceHub: ServiceHubInternal)
private fun findByIdentityKey(session: Session, identityKey: PublicKey): List<NodeInfoSchemaV1.PersistentNodeInfo> { private fun findByIdentityKey(session: Session, identityKey: PublicKey): List<NodeInfoSchemaV1.PersistentNodeInfo> {
val query = session.createQuery( val query = session.createQuery(
"SELECT n FROM ${NodeInfoSchemaV1.PersistentNodeInfo::class.java.name} n JOIN n.legalIdentitiesAndCerts l WHERE l.owningKey = :owningKey", "SELECT n FROM ${NodeInfoSchemaV1.PersistentNodeInfo::class.java.name} n JOIN n.legalIdentitiesAndCerts l WHERE l.owningKeyHash = :owningKeyHash",
NodeInfoSchemaV1.PersistentNodeInfo::class.java) NodeInfoSchemaV1.PersistentNodeInfo::class.java)
query.setParameter("owningKey", identityKey.toBase58String()) query.setParameter("owningKeyHash", identityKey.toStringShort())
return query.resultList return query.resultList
} }

View File

@ -7,9 +7,9 @@ import net.corda.core.messaging.SingleMessageRecipient
import net.corda.core.serialization.SerializationDefaults import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.services.api.NetworkMapCacheInternal import net.corda.node.services.api.NetworkMapCacheInternal
import net.corda.node.services.messaging.MessagingService import net.corda.node.services.messaging.MessagingService
import net.corda.node.utilities.MAX_HASH_HEX_SIZE
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.NODE_DATABASE_PREFIX
import net.corda.node.utilities.PersistentMap import net.corda.node.utilities.PersistentMap
import net.corda.nodeapi.ArtemisMessagingComponent import net.corda.nodeapi.ArtemisMessagingComponent

View File

@ -3,6 +3,7 @@ package net.corda.node.services.transactions
import co.paralleluniverse.fibers.Suspendable import co.paralleluniverse.fibers.Suspendable
import com.google.common.util.concurrent.SettableFuture import com.google.common.util.concurrent.SettableFuture
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.DigitalSignature import net.corda.core.crypto.DigitalSignature
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.flows.FlowLogic import net.corda.core.flows.FlowLogic
@ -15,6 +16,7 @@ import net.corda.core.node.services.NotaryService
import net.corda.core.node.services.TimeWindowChecker import net.corda.core.node.services.TimeWindowChecker
import net.corda.core.node.services.UniquenessProvider import net.corda.core.node.services.UniquenessProvider
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.deserialize import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize import net.corda.core.serialization.serialize
import net.corda.core.transactions.FilteredTransaction import net.corda.core.transactions.FilteredTransaction
@ -110,7 +112,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal,
inputIndex = it.consumingIndex, inputIndex = it.consumingIndex,
requestingParty = Party( requestingParty = Party(
name = CordaX500Name.parse(it.party.name), name = CordaX500Name.parse(it.party.name),
owningKey = parsePublicKeyBase58(it.party.owningKey)))) owningKey = Crypto.decodePublicKey(it.party.owningKey))))
}, },
toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx -> toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
PersistedCommittedState( PersistedCommittedState(
@ -118,7 +120,7 @@ class BFTNonValidatingNotaryService(override val services: ServiceHubInternal,
consumingTxHash = id.toString(), consumingTxHash = id.toString(),
consumingIndex = inputIndex, consumingIndex = inputIndex,
party = PersistentUniquenessProvider.PersistentParty(requestingParty.name.toString(), party = PersistentUniquenessProvider.PersistentParty(requestingParty.name.toString(),
requestingParty.owningKey.toBase58String()) requestingParty.owningKey.encoded)
) )
}, },
persistentEntityClass = PersistedCommittedState::class.java persistentEntityClass = PersistedCommittedState::class.java

View File

@ -1,6 +1,7 @@
package net.corda.node.services.transactions package net.corda.node.services.transactions
import net.corda.core.contracts.StateRef import net.corda.core.contracts.StateRef
import net.corda.core.crypto.Crypto
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
@ -8,10 +9,11 @@ import net.corda.core.internal.ThreadBox
import net.corda.core.node.services.UniquenessException import net.corda.core.node.services.UniquenessException
import net.corda.core.node.services.UniquenessProvider import net.corda.core.node.services.UniquenessProvider
import net.corda.core.schemas.PersistentStateRef import net.corda.core.schemas.PersistentStateRef
import net.corda.core.serialization.SerializationDefaults
import net.corda.core.serialization.SingletonSerializeAsToken import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.serialization.deserialize
import net.corda.core.serialization.serialize
import net.corda.core.utilities.loggerFor import net.corda.core.utilities.loggerFor
import net.corda.core.utilities.parsePublicKeyBase58
import net.corda.core.utilities.toBase58String
import net.corda.node.utilities.AppendOnlyPersistentMap import net.corda.node.utilities.AppendOnlyPersistentMap
import net.corda.node.utilities.NODE_DATABASE_PREFIX import net.corda.node.utilities.NODE_DATABASE_PREFIX
import java.io.Serializable import java.io.Serializable
@ -44,7 +46,7 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
var name: String = "", var name: String = "",
@Column(name = "requesting_party_key", length = 255) @Column(name = "requesting_party_key", length = 255)
var owningKey: String = "" var owningKey: ByteArray = ByteArray(0)
) : Serializable ) : Serializable
@Entity @Entity
@ -75,14 +77,14 @@ class PersistentUniquenessProvider : UniquenessProvider, SingletonSerializeAsTok
inputIndex = it.consumingIndex, inputIndex = it.consumingIndex,
requestingParty = Party( requestingParty = Party(
name = CordaX500Name.parse(it.party.name), name = CordaX500Name.parse(it.party.name),
owningKey = parsePublicKeyBase58(it.party.owningKey)))) owningKey = Crypto.decodePublicKey(it.party.owningKey))))
}, },
toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx -> toPersistentEntity = { (txHash, index): StateRef, (id, inputIndex, requestingParty): UniquenessProvider.ConsumingTx ->
PersistentNotaryCommit( PersistentNotaryCommit(
id = PersistentStateRef(txHash.toString(), index), id = PersistentStateRef(txHash.toString(), index),
consumingTxHash = id.toString(), consumingTxHash = id.toString(),
consumingIndex = inputIndex, consumingIndex = inputIndex,
party = PersistentParty(requestingParty.name.toString(), requestingParty.owningKey.toBase58String()) party = PersistentParty(requestingParty.name.toString(), requestingParty.owningKey.encoded)
) )
}, },
persistentEntityClass = PersistentNotaryCommit::class.java persistentEntityClass = PersistentNotaryCommit::class.java

View File

@ -20,14 +20,6 @@ import java.util.concurrent.CopyOnWriteArrayList
*/ */
const val NODE_DATABASE_PREFIX = "node_" const val NODE_DATABASE_PREFIX = "node_"
/**
* The maximum supported field-size for hash HEX-encoded outputs (e.g. database fields).
* This value is enough to support hash functions with outputs up to 512 bits (e.g. SHA3-512), in which
* case 128 HEX characters are required.
* 130 was selected instead of 128, to allow for 2 extra characters that will be used as hash-scheme identifiers.
*/
internal const val MAX_HASH_HEX_SIZE = 130
//HikariDataSource implements Closeable which allows CordaPersistence to be Closeable //HikariDataSource implements Closeable which allows CordaPersistence to be Closeable
class CordaPersistence(var dataSource: HikariDataSource, private val schemaService: SchemaService, class CordaPersistence(var dataSource: HikariDataSource, private val schemaService: SchemaService,
private val createIdentityService: () -> IdentityService, databaseProperties: Properties) : Closeable { private val createIdentityService: () -> IdentityService, databaseProperties: Properties) : Closeable {

View File

@ -448,7 +448,7 @@ class HibernateConfigurationTest : TestDependencyInjectionBase() {
criteriaBuilder.sum(cashStates.get<Long>("pennies"))) criteriaBuilder.sum(cashStates.get<Long>("pennies")))
// group by // group by
criteriaQuery.groupBy(cashStates.get<String>("issuerParty"), cashStates.get<String>("currency")) criteriaQuery.groupBy(cashStates.get<String>("issuerPartyHash"), cashStates.get<String>("currency"))
// order by // order by
criteriaQuery.orderBy(criteriaBuilder.desc(criteriaBuilder.sum(cashStates.get<Long>("pennies")))) criteriaQuery.orderBy(criteriaBuilder.desc(criteriaBuilder.sum(cashStates.get<Long>("pennies"))))

View File

@ -3,6 +3,7 @@ package net.corda.node.services.vault
import net.corda.core.contracts.* import net.corda.core.contracts.*
import net.corda.core.crypto.SecureHash import net.corda.core.crypto.SecureHash
import net.corda.core.crypto.entropyToKeyPair import net.corda.core.crypto.entropyToKeyPair
import net.corda.core.crypto.toStringShort
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
@ -693,7 +694,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L)) services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
} }
database.transaction { database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerParty.isNull() } val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerPartyHash.isNull() }
val criteria = VaultCustomQueryCriteria(logicalExpression) val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria) val results = vaultService.queryBy<Cash.State>(criteria)
assertThat(results.states).hasSize(0) assertThat(results.states).hasSize(0)
@ -708,7 +709,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L)) services.fillWithSomeTestCash(100.SWISS_FRANCS, notaryServices, DUMMY_NOTARY, 1, 1, Random(0L))
} }
database.transaction { database.transaction {
val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerParty.notNull() } val logicalExpression = builder { CashSchemaV1.PersistentCashState::issuerPartyHash.notNull() }
val criteria = VaultCustomQueryCriteria(logicalExpression) val criteria = VaultCustomQueryCriteria(logicalExpression)
val results = vaultService.queryBy<Cash.State>(criteria) val results = vaultService.queryBy<Cash.State>(criteria)
assertThat(results.states).hasSize(3) assertThat(results.states).hasSize(3)
@ -830,7 +831,7 @@ class VaultQueryTests : TestDependencyInjectionBase() {
database.transaction { database.transaction {
// DOCSTART VaultQueryExample23 // DOCSTART VaultQueryExample23
val sum = builder { val sum = builder {
CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::issuerParty, CashSchemaV1.PersistentCashState::pennies.sum(groupByColumns = listOf(CashSchemaV1.PersistentCashState::issuerPartyHash,
CashSchemaV1.PersistentCashState::currency), CashSchemaV1.PersistentCashState::currency),
orderBy = Sort.Direction.DESC) orderBy = Sort.Direction.DESC)
} }
@ -841,16 +842,16 @@ class VaultQueryTests : TestDependencyInjectionBase() {
assertThat(results.otherResults).hasSize(12) assertThat(results.otherResults).hasSize(12)
assertThat(results.otherResults[0]).isEqualTo(40000L) assertThat(results.otherResults[0]).isEqualTo(40000L)
assertThat(results.otherResults[1]).isEqualTo(BOC_PUBKEY.toBase58String()) assertThat(results.otherResults[1]).isEqualTo(BOC_PUBKEY.toStringShort())
assertThat(results.otherResults[2]).isEqualTo("GBP") assertThat(results.otherResults[2]).isEqualTo("GBP")
assertThat(results.otherResults[3]).isEqualTo(30000L) assertThat(results.otherResults[3]).isEqualTo(30000L)
assertThat(results.otherResults[4]).isEqualTo(DUMMY_CASH_ISSUER.party.owningKey.toBase58String()) assertThat(results.otherResults[4]).isEqualTo(DUMMY_CASH_ISSUER.party.owningKey.toStringShort())
assertThat(results.otherResults[5]).isEqualTo("GBP") assertThat(results.otherResults[5]).isEqualTo("GBP")
assertThat(results.otherResults[6]).isEqualTo(20000L) assertThat(results.otherResults[6]).isEqualTo(20000L)
assertThat(results.otherResults[7]).isEqualTo(BOC_PUBKEY.toBase58String()) assertThat(results.otherResults[7]).isEqualTo(BOC_PUBKEY.toStringShort())
assertThat(results.otherResults[8]).isEqualTo("USD") assertThat(results.otherResults[8]).isEqualTo("USD")
assertThat(results.otherResults[9]).isEqualTo(10000L) assertThat(results.otherResults[9]).isEqualTo(10000L)
assertThat(results.otherResults[10]).isEqualTo(DUMMY_CASH_ISSUER.party.owningKey.toBase58String()) assertThat(results.otherResults[10]).isEqualTo(DUMMY_CASH_ISSUER.party.owningKey.toStringShort())
assertThat(results.otherResults[11]).isEqualTo("USD") assertThat(results.otherResults[11]).isEqualTo("USD")
} }
} }