Resloved merge conflicts.

This commit is contained in:
szymonsztuka 2018-05-29 11:32:43 +01:00
commit c6168cb4e6
50 changed files with 255 additions and 164 deletions

View File

@ -4339,21 +4339,19 @@ public class net.corda.core.schemas.PersistentState extends java.lang.Object imp
@Embeddable @Embeddable
public class net.corda.core.schemas.PersistentStateRef extends java.lang.Object implements java.io.Serializable public class net.corda.core.schemas.PersistentStateRef extends java.lang.Object implements java.io.Serializable
public <init>() public <init>()
public <init>(String, Integer) public <init>(String, int)
public <init>(net.corda.core.contracts.StateRef) public <init>(net.corda.core.contracts.StateRef)
@Nullable
public final String component1()
@Nullable
public final Integer component2()
@NotNull @NotNull
public final net.corda.core.schemas.PersistentStateRef copy(String, Integer) public final String component1()
public final int component2()
@NotNull
public final net.corda.core.schemas.PersistentStateRef copy(String, int)
public boolean equals(Object) public boolean equals(Object)
@Nullable public int getIndex()
public Integer getIndex() @NotNull
@Nullable
public String getTxId() public String getTxId()
public int hashCode() public int hashCode()
public void setIndex(Integer) public void setIndex(int)
public void setTxId(String) public void setTxId(String)
public String toString() public String toString()
## ##

View File

@ -76,7 +76,7 @@ see changes to this list.
* George Smetana (Bradesco) * George Smetana (Bradesco)
* Giulio Katis (Westpac) * Giulio Katis (Westpac)
* Giuseppe Cardone (Intesa Sanpaolo) * Giuseppe Cardone (Intesa Sanpaolo)
* Guy Hochstetler (IBM) * Guy Hochstetler (R3)
* Ian Cusden (UBS) * Ian Cusden (UBS)
* Ian Grigg (R3) * Ian Grigg (R3)
* Igor Nitto (R3) * Igor Nitto (R3)

View File

@ -49,6 +49,7 @@ import net.corda.core.utilities.toBase58String
import org.bouncycastle.asn1.x509.KeyPurposeId import org.bouncycastle.asn1.x509.KeyPurposeId
import java.lang.reflect.Modifier import java.lang.reflect.Modifier
import java.math.BigDecimal import java.math.BigDecimal
import java.nio.charset.StandardCharsets.UTF_8
import java.security.PublicKey import java.security.PublicKey
import java.security.cert.CertPath import java.security.cert.CertPath
import java.security.cert.CertificateFactory import java.security.cert.CertificateFactory
@ -426,7 +427,7 @@ object JacksonSupport {
@Deprecated("This is an internal class, do not use") @Deprecated("This is an internal class, do not use")
object OpaqueBytesDeserializer : JsonDeserializer<OpaqueBytes>() { object OpaqueBytesDeserializer : JsonDeserializer<OpaqueBytes>() {
override fun deserialize(parser: JsonParser, ctxt: DeserializationContext): OpaqueBytes { override fun deserialize(parser: JsonParser, ctxt: DeserializationContext): OpaqueBytes {
return OpaqueBytes(parser.binaryValue) return OpaqueBytes(parser.text?.toByteArray(UTF_8) ?: parser.binaryValue)
} }
} }

View File

@ -49,6 +49,7 @@ import org.junit.runner.RunWith
import org.junit.runners.Parameterized import org.junit.runners.Parameterized
import org.junit.runners.Parameterized.Parameters import org.junit.runners.Parameterized.Parameters
import java.math.BigInteger import java.math.BigInteger
import java.nio.charset.StandardCharsets.*
import java.security.PublicKey import java.security.PublicKey
import java.security.cert.CertPath import java.security.cert.CertPath
import java.security.cert.X509Certificate import java.security.cert.X509Certificate
@ -113,12 +114,17 @@ class JacksonSupportTest(@Suppress("unused") private val name: String, factory:
} }
@Test @Test
fun OpaqueBytes() { fun `OpaqueBytes serialization`() {
val opaqueBytes = OpaqueBytes(secureRandomBytes(128)) val opaqueBytes = OpaqueBytes(secureRandomBytes(128))
val json = mapper.valueToTree<BinaryNode>(opaqueBytes) val json = mapper.valueToTree<BinaryNode>(opaqueBytes)
assertThat(json.binaryValue()).isEqualTo(opaqueBytes.bytes) assertThat(json.binaryValue()).isEqualTo(opaqueBytes.bytes)
assertThat(json.asText()).isEqualTo(opaqueBytes.bytes.toBase64()) assertThat(json.asText()).isEqualTo(opaqueBytes.bytes.toBase64())
assertThat(mapper.convertValue<OpaqueBytes>(json)).isEqualTo(opaqueBytes) }
@Test
fun `OpaqueBytes deserialization`() {
assertThat(mapper.convertValue<OpaqueBytes>(TextNode("1234"))).isEqualTo(OpaqueBytes("1234".toByteArray(UTF_8)))
assertThat(mapper.convertValue<OpaqueBytes>(BinaryNode(byteArrayOf(1, 2, 3, 4)))).isEqualTo(OpaqueBytes.of(1, 2, 3, 4))
} }
@Test @Test

View File

@ -13,6 +13,7 @@ package net.corda.core.node
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.node.services.AttachmentId import net.corda.core.node.services.AttachmentId
import net.corda.core.serialization.CordaSerializable import net.corda.core.serialization.CordaSerializable
import net.corda.core.serialization.DeprecatedConstructorForDeserialization
import net.corda.core.utilities.days import net.corda.core.utilities.days
import java.time.Duration import java.time.Duration
import java.time.Instant import java.time.Instant
@ -33,7 +34,7 @@ import java.time.Instant
* during this period * during this period
*/ */
@CordaSerializable @CordaSerializable
data class NetworkParameters @JvmOverloads constructor( data class NetworkParameters(
val minimumPlatformVersion: Int, val minimumPlatformVersion: Int,
val notaries: List<NotaryInfo>, val notaries: List<NotaryInfo>,
val maxMessageSize: Int, val maxMessageSize: Int,
@ -41,8 +42,26 @@ data class NetworkParameters @JvmOverloads constructor(
val modifiedTime: Instant, val modifiedTime: Instant,
val epoch: Int, val epoch: Int,
val whitelistedContractImplementations: Map<String, List<AttachmentId>>, val whitelistedContractImplementations: Map<String, List<AttachmentId>>,
val eventHorizon: Duration = Int.MAX_VALUE.days val eventHorizon: Duration
) { ) {
@DeprecatedConstructorForDeserialization(1)
constructor (minimumPlatformVersion: Int,
notaries: List<NotaryInfo>,
maxMessageSize: Int,
maxTransactionSize: Int,
modifiedTime: Instant,
epoch: Int,
whitelistedContractImplementations: Map<String, List<AttachmentId>>
) : this(minimumPlatformVersion,
notaries,
maxMessageSize,
maxTransactionSize,
modifiedTime,
epoch,
whitelistedContractImplementations,
Int.MAX_VALUE.days
)
init { init {
require(minimumPlatformVersion > 0) { "minimumPlatformVersion must be at least 1" } require(minimumPlatformVersion > 0) { "minimumPlatformVersion must be at least 1" }
require(notaries.distinctBy { it.identity } == notaries) { "Duplicate notary identities" } require(notaries.distinctBy { it.identity } == notaries) { "Duplicate notary identities" }

View File

@ -66,7 +66,7 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
/** [OwnableState] attributes */ /** [OwnableState] attributes */
/** X500Name of owner party **/ /** X500Name of owner party **/
@Column(name = "owner_name") @Column(name = "owner_name", nullable = true)
var owner: AbstractParty, var owner: AbstractParty,
/** [FungibleAsset] attributes /** [FungibleAsset] attributes
@ -76,16 +76,16 @@ object CommonSchemaV1 : MappedSchema(schemaFamily = CommonSchema.javaClass, vers
*/ */
/** Amount attributes */ /** Amount attributes */
@Column(name = "quantity") @Column(name = "quantity", nullable = false)
var quantity: Long, var quantity: Long,
/** Issuer attributes */ /** Issuer attributes */
/** X500Name of issuer party **/ /** X500Name of issuer party **/
@Column(name = "issuer_name") @Column(name = "issuer_name", nullable = true)
var issuer: AbstractParty, var issuer: AbstractParty,
@Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -97,11 +97,11 @@ class PersistentState(@EmbeddedId var stateRef: PersistentStateRef? = null) : St
*/ */
@Embeddable @Embeddable
data class PersistentStateRef( data class PersistentStateRef(
@Column(name = "transaction_id", length = 64) @Column(name = "transaction_id", length = 64, nullable = false)
var txId: String? = null, var txId: String,
@Column(name = "output_index") @Column(name = "output_index", nullable = false)
var index: Int? = null var index: Int
) : Serializable { ) : Serializable {
constructor(stateRef: StateRef) : this(stateRef.txhash.bytes.toHexString(), stateRef.index) constructor(stateRef: StateRef) : this(stateRef.txhash.bytes.toHexString(), stateRef.index)
} }

View File

@ -97,6 +97,12 @@ Unreleased
reference to the outer class) as per the Java documentation `here <https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>`_ reference to the outer class) as per the Java documentation `here <https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html>`_
we are disallowing this as the paradigm in general makes little sense for contract states. we are disallowing this as the paradigm in general makes little sense for contract states.
* API change: ``net.corda.core.schemas.PersistentStateRef`` fields (index and txId) are now non-nullable.
The fields were always effectively non-nullable - values were set from non-nullable fields of other objects.
The class is used as database Primary Key columns of other entities and databases already impose those columns as non-nullable
(even if JPA annotation nullable=false was absent).
In case your Cordapps use this entity class to persist data in own custom tables as non Primary Key columns refer to :doc:`upgrade-notes` for upgrade instructions.
* Update the fast-classpath-scanner dependent library version from 2.0.21 to 2.12.3 * Update the fast-classpath-scanner dependent library version from 2.0.21 to 2.12.3
* Added `database.hibernateDialect` node configuration option * Added `database.hibernateDialect` node configuration option

View File

@ -208,7 +208,7 @@ absolute path to the node's base directory.
:sshd: If provided, node will start internal SSH server which will provide a management shell. It uses the same credentials and permissions as RPC subsystem. It has one required parameter. :sshd: If provided, node will start internal SSH server which will provide a management shell. It uses the same credentials and permissions as RPC subsystem. It has one required parameter.
:port: The port to start SSH server on :port: The port to start SSH server on e.g. ``sshd { port = 2222 }``.
:relay: If provided, the node will attempt to tunnel inbound connections via an external relay. The relay's address will be :relay: If provided, the node will attempt to tunnel inbound connections via an external relay. The relay's address will be
advertised to the network map service instead of the provided ``p2pAddress``. advertised to the network map service instead of the provided ``p2pAddress``.

View File

@ -64,7 +64,7 @@ above. A sensible default for the missing value is provided for instantiation of
order, see the discussion below. order, see the discussion below.
As before, instances of the class at version A will be able to deserialize serialized forms of example B as it As before, instances of the class at version A will be able to deserialize serialized forms of example B as it
will simply treat them as if the property has been removed (as from its perspective, they will have been.) will simply treat them as if the property has been removed (as from its perspective, they will have been).
Constructor Versioning Constructor Versioning
@ -144,7 +144,6 @@ be:
// The third alteration, and how it currently exists, property e added // The third alteration, and how it currently exists, property e added
data class Example3 (val a: Int, val b: Int, val c: Int, val d: Int, val: Int e) { data class Example3 (val a: Int, val b: Int, val c: Int, val d: Int, val: Int e) {
// NOTE: version number purposefully omitted from annotation for demonstration purposes
@DeprecatedConstructorForDeserialization(1) @DeprecatedConstructorForDeserialization(1)
constructor (a: Int, b: Int) : this(a, b, -1, -1, -1) // alt constructor 1 constructor (a: Int, b: Int) : this(a, b, -1, -1, -1) // alt constructor 1
@DeprecatedConstructorForDeserialization(2) @DeprecatedConstructorForDeserialization(2)

View File

@ -269,9 +269,9 @@ SecureHash
~~~~~~~~~~ ~~~~~~~~~~
A parameter of type ``SecureHash`` can be written as a hexadecimal string: ``F69A7626ACC27042FEEAE187E6BFF4CE666E6F318DC2B32BE9FAF87DF687930C`` A parameter of type ``SecureHash`` can be written as a hexadecimal string: ``F69A7626ACC27042FEEAE187E6BFF4CE666E6F318DC2B32BE9FAF87DF687930C``
OpaqueBytes and SerializedBytes OpaqueBytes
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~
A parameter of type ``OpaqueBytes`` can be provided as a string in Base64. A parameter of type ``OpaqueBytes`` can be provided as a UTF-8 string.
PublicKey and CompositeKey PublicKey and CompositeKey
~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -29,6 +29,44 @@ versions you are currently using are still in force.
We also strongly recommend cross referencing with the :doc:`changelog` to confirm changes. We also strongly recommend cross referencing with the :doc:`changelog` to confirm changes.
UNRELEASED
----------
<<< Fill this in >>>
* API change: ``net.corda.core.schemas.PersistentStateRef`` fields (``index`` and ``txId``) incorrectly marked as nullable are now non-nullable,
:doc:`changelog` contains the explanation.
H2 database upgrade action:
For Cordapps persisting custom entities with ``PersistentStateRef`` used as non Primary Key column, the backing table needs to be updated,
In SQL replace ``your_transaction_id``/``your_output_index`` column names with your custom names, if entity didn't used JPA ``@AttributeOverrides``
then default names are ``transaction_id`` and ``output_index``.
.. sourcecode:: sql
SELECT count(*) FROM [YOUR_PersistentState_TABLE_NAME] WHERE your_transaction_id IS NULL OR your_output_index IS NULL;
In case your table already contains rows with NULL columns, and the logic doesn't distinguish between NULL and an empty string,
all NULL column occurrences can be changed to an empty string:
.. sourcecode:: sql
UPDATE [YOUR_PersistentState_TABLE_NAME] SET your_transaction_id="" WHERE your_transaction_id IS NULL;
UPDATE [YOUR_PersistentState_TABLE_NAME] SET your_output_index="" WHERE your_output_index IS NULL;
If all rows have NON NULL ``transaction_ids`` and ``output_idx`` or you have assigned empty string values, then it's safe to update the table:
.. sourcecode:: sql
ALTER TABLE [YOUR_PersistentState_TABLE_NAME] ALTER COLUMN your_transaction_id SET NOT NULL;
ALTER TABLE [YOUR_PersistentState_TABLE_NAME] ALTER COLUMN your_output_index SET NOT NULL;
If the table already contains rows with NULL values, and the logic caters differently between NULL and an empty string,
and the logic has to be preserved you would need to create copy of ``PersistentStateRef`` class with different name and use the new class in your entity.
No action is needed for default node tables as ``PersistentStateRef`` is used as Primary Key only and the backing columns are automatically not nullable
or custom Cordapp entities using ``PersistentStateRef`` as Primary Key.
Upgrading to R3 Corda V3.0 Developer Preview Upgrading to R3 Corda V3.0 Developer Preview
-------------------------------------------- --------------------------------------------

View File

@ -25,6 +25,9 @@ import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection import net.corda.finance.contracts.asset.cash.selection.AbstractCashSelection
import net.corda.finance.flows.AbstractCashFlow.Companion.FINALISING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.GENERATING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.finance.issuedBy import net.corda.finance.issuedBy
import java.util.* import java.util.*

View File

@ -19,6 +19,9 @@ import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.OpaqueBytes import net.corda.core.utilities.OpaqueBytes
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.AbstractCashFlow.Companion.FINALISING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.GENERATING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.SIGNING_TX
import net.corda.finance.issuedBy import net.corda.finance.issuedBy
import java.util.* import java.util.*

View File

@ -21,6 +21,10 @@ import net.corda.core.serialization.CordaSerializable
import net.corda.core.transactions.TransactionBuilder import net.corda.core.transactions.TransactionBuilder
import net.corda.core.utilities.ProgressTracker import net.corda.core.utilities.ProgressTracker
import net.corda.finance.contracts.asset.Cash import net.corda.finance.contracts.asset.Cash
import net.corda.finance.flows.AbstractCashFlow.Companion.FINALISING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.GENERATING_ID
import net.corda.finance.flows.AbstractCashFlow.Companion.GENERATING_TX
import net.corda.finance.flows.AbstractCashFlow.Companion.SIGNING_TX
import java.util.* import java.util.*
/** /**

View File

@ -38,19 +38,19 @@ object CashSchemaV1 : MappedSchema(
@Table(name = "contract_cash_states", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")]) @Table(name = "contract_cash_states", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")])
class PersistentCashState( class PersistentCashState(
/** X500Name of owner party **/ /** X500Name of owner party **/
@Column(name = "owner_name") @Column(name = "owner_name", nullable = true)
var owner: AbstractParty, var owner: AbstractParty,
@Column(name = "pennies") @Column(name = "pennies", nullable = false)
var pennies: Long, var pennies: Long,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
@Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var issuerPartyHash: String, var issuerPartyHash: String,
@Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -40,29 +40,29 @@ object CommercialPaperSchemaV1 : MappedSchema(
@Entity @Entity
@Table(name = "cp_states", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")]) @Table(name = "cp_states", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")])
class PersistentCommercialPaperState( class PersistentCommercialPaperState(
@Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var issuancePartyHash: String, var issuancePartyHash: String,
@Column(name = "issuance_ref") @Column(name = "issuance_ref", nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuanceRef: ByteArray, var issuanceRef: ByteArray,
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var ownerHash: String, var ownerHash: String,
@Column(name = "maturity_instant") @Column(name = "maturity_instant", nullable = false)
var maturity: Instant, var maturity: Instant,
@Column(name = "face_value") @Column(name = "face_value", nullable = false)
var faceValue: Long, var faceValue: Long,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var faceValueIssuerPartyHash: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var faceValueIssuerRef: ByteArray var faceValueIssuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -254,7 +254,7 @@ class CommercialPaperTestsGeneric {
// MegaCorp will issue some commercial paper and Alice will buy it, using cash issued to her in the name // MegaCorp will issue some commercial paper and Alice will buy it, using cash issued to her in the name
// of the dummy cash issuer. // of the dummy cash issuer.
val allIdentities = arrayOf(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity) val allIdentities = arrayOf(megaCorp.identity, alice.identity, dummyCashIssuer.identity, dummyNotary.identity)
val notaryServices = MockServices(dummyNotary) val notaryServices = MockServices(dummyNotary)
val issuerServices = MockServices(dummyCashIssuer, dummyNotary) val issuerServices = MockServices(dummyCashIssuer, dummyNotary)
val (aliceDatabase, aliceServices) = makeTestDatabaseAndMockServices( val (aliceDatabase, aliceServices) = makeTestDatabaseAndMockServices(

View File

@ -92,10 +92,11 @@ class CashTests {
LogHelper.setLevel(NodeVaultService::class) LogHelper.setLevel(NodeVaultService::class)
megaCorpServices = MockServices(megaCorp) megaCorpServices = MockServices(megaCorp)
miniCorpServices = MockServices(miniCorp) miniCorpServices = MockServices(miniCorp)
val myself = TestIdentity(CordaX500Name("Me", "London", "GB"))
val databaseAndServices = makeTestDatabaseAndMockServices( val databaseAndServices = makeTestDatabaseAndMockServices(
listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"), listOf("net.corda.finance.contracts.asset", "net.corda.finance.schemas"),
makeTestIdentityService(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity), makeTestIdentityService(megaCorp.identity, miniCorp.identity, dummyCashIssuer.identity, dummyNotary.identity, myself.identity),
TestIdentity(CordaX500Name("Me", "London", "GB")) myself
) )
database = databaseAndServices.first database = databaseAndServices.first
ourServices = databaseAndServices.second ourServices = databaseAndServices.second

View File

@ -36,19 +36,19 @@ object SampleCashSchemaV1 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
@Entity @Entity
@Table(name = "contract_cash_states_v1", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")]) @Table(name = "contract_cash_states_v1", indexes = [Index(name = "ccy_code_idx", columnList = "ccy_code"), Index(name = "pennies_idx", columnList = "pennies")])
class PersistentCashState( class PersistentCashState(
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var ownerHash: String, var ownerHash: String,
@Column(name = "pennies") @Column(name = "pennies", nullable = false)
var pennies: Long, var pennies: Long,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
@Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "issuer_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var issuerPartyHash: String, var issuerPartyHash: String,
@Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -28,7 +28,7 @@ object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
@Table(name = "cash_states_v2", indexes = [Index(name = "ccy_code_idx2", columnList = "ccy_code")]) @Table(name = "cash_states_v2", indexes = [Index(name = "ccy_code_idx2", columnList = "ccy_code")])
class PersistentCashState( class PersistentCashState(
/** product type */ /** product type */
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
participants: Set<AbstractParty>, participants: Set<AbstractParty>,
owner: AbstractParty, owner: AbstractParty,
@ -38,7 +38,7 @@ object SampleCashSchemaV2 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
) : CommonSchemaV1.FungibleState(participants.toMutableSet(), owner, quantity, issuerParty, issuerRef.bytes) { ) : CommonSchemaV1.FungibleState(participants.toMutableSet(), owner, quantity, issuerParty, issuerRef.bytes) {
@ElementCollection @ElementCollection
@Column(name = "participants") @Column(name = "participants", nullable = true)
@CollectionTable(name = "cash_states_v2_participants", joinColumns = [JoinColumn(name = "output_index", referencedColumnName = "output_index"), JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")]) @CollectionTable(name = "cash_states_v2_participants", joinColumns = [JoinColumn(name = "output_index", referencedColumnName = "output_index"), JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id")])
override var participants: MutableSet<AbstractParty>? = null override var participants: MutableSet<AbstractParty>? = null
} }

View File

@ -39,20 +39,20 @@ object SampleCashSchemaV3 : MappedSchema(schemaFamily = CashSchema.javaClass, ve
var participants: MutableSet<AbstractParty>? = null, var participants: MutableSet<AbstractParty>? = null,
/** X500Name of owner party **/ /** X500Name of owner party **/
@Column(name = "owner_name") @Column(name = "owner_name", nullable = true)
var owner: AbstractParty, var owner: AbstractParty,
@Column(name = "pennies") @Column(name = "pennies", nullable = false)
var pennies: Long, var pennies: Long,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
/** X500Name of issuer party **/ /** X500Name of issuer party **/
@Column(name = "issuer_name") @Column(name = "issuer_name", nullable = true)
var issuer: AbstractParty, var issuer: AbstractParty,
@Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -37,29 +37,29 @@ object SampleCommercialPaperSchemaV1 : MappedSchema(schemaFamily = CommercialPap
@Entity @Entity
@Table(name = "cp_states_v1", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")]) @Table(name = "cp_states_v1", indexes = [Index(name = "ccy_code_index", columnList = "ccy_code"), Index(name = "maturity_index", columnList = "maturity_instant"), Index(name = "face_value_index", columnList = "face_value")])
class PersistentCommercialPaperState( class PersistentCommercialPaperState(
@Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "issuance_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var issuancePartyHash: String, var issuancePartyHash: String,
@Column(name = "issuance_ref") @Column(name = "issuance_ref", nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuanceRef: ByteArray, var issuanceRef: ByteArray,
@Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "owner_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var ownerHash: String, var ownerHash: String,
@Column(name = "maturity_instant") @Column(name = "maturity_instant", nullable = false)
var maturity: Instant, var maturity: Instant,
@Column(name = "face_value") @Column(name = "face_value", nullable = false)
var faceValue: Long, var faceValue: Long,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var faceValueIssuerPartyHash: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var faceValueIssuerRef: ByteArray var faceValueIssuerRef: ByteArray
) : PersistentState() ) : PersistentState()

View File

@ -32,16 +32,16 @@ object SampleCommercialPaperSchemaV2 : MappedSchema(schemaFamily = CommercialPap
@Entity @Entity
@Table(name = "cp_states_v2", indexes = [Index(name = "ccy_code_index2", columnList = "ccy_code"), Index(name = "maturity_index2", columnList = "maturity_instant")]) @Table(name = "cp_states_v2", indexes = [Index(name = "ccy_code_index2", columnList = "ccy_code"), Index(name = "maturity_index2", columnList = "maturity_instant")])
class PersistentCommercialPaperState( class PersistentCommercialPaperState(
@Column(name = "maturity_instant") @Column(name = "maturity_instant", nullable = false)
var maturity: Instant, var maturity: Instant,
@Column(name = "ccy_code", length = 3) @Column(name = "ccy_code", length = 3, nullable = false)
var currency: String, var currency: String,
@Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "face_value_issuer_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var faceValueIssuerPartyHash: String, var faceValueIssuerPartyHash: String,
@Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "face_value_issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var faceValueIssuerRef: ByteArray, var faceValueIssuerRef: ByteArray,

View File

@ -42,10 +42,10 @@ object MessageSchemaV1 : MappedSchema(
@Entity @Entity
@Table(name = "messages") @Table(name = "messages")
class PersistentMessage( class PersistentMessage(
@Column(name = "message_by") @Column(name = "message_by", nullable = false)
var by: String, var by: String,
@Column(name = "message_value") @Column(name = "message_value", nullable = false)
var value: String var value: String
) : PersistentState() ) : PersistentState()
} }

View File

@ -305,8 +305,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val identityService = makeIdentityService(identity.certificate) val identityService = makeIdentityService(identity.certificate)
networkMapClient = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, identityService.trustRoot) } networkMapClient = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, identityService.trustRoot) }
val networkParameteresReader = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory)
val networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters val networkParameters = networkParameteresReader.networkParameters
check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) { check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) {
"Node's platform version is lower than network's required minimumPlatformVersion" "Node's platform version is lower than network's required minimumPlatformVersion"
} }
@ -384,7 +384,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
networkMapUpdater = NetworkMapUpdater(services.networkMapCache, networkMapUpdater = NetworkMapUpdater(services.networkMapCache,
NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)), NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)),
networkMapClient, networkMapClient,
networkParameters.serialize().hash, networkParameteresReader.hash,
services.myInfo.serialize().hash, services.myInfo.serialize().hash,
configuration.baseDirectory, configuration.baseDirectory,
configuration.extraNetworkMapKeys) configuration.extraNetworkMapKeys)

View File

@ -31,11 +31,14 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
private val logger = contextLogger() private val logger = contextLogger()
} }
private data class NetworkParamsAndHash(val networkParameters: NetworkParameters, val hash: SecureHash)
private val networkParamsFile = baseDirectory / NETWORK_PARAMS_FILE_NAME private val networkParamsFile = baseDirectory / NETWORK_PARAMS_FILE_NAME
private val parametersUpdateFile = baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME private val parametersUpdateFile = baseDirectory / NETWORK_PARAMS_UPDATE_FILE_NAME
val networkParameters by lazy { retrieveNetworkParameters() } private val netParamsAndHash by lazy { retrieveNetworkParameters() }
val networkParameters get() = netParamsAndHash.networkParameters
val hash get() = netParamsAndHash.hash
private fun retrieveNetworkParameters(): NetworkParameters { private fun retrieveNetworkParameters(): NetworkParamsAndHash {
val advertisedParametersHash = try { val advertisedParametersHash = try {
networkMapClient?.getNetworkMap()?.payload?.networkParameterHash networkMapClient?.getNetworkMap()?.payload?.networkParameterHash
} catch (e: Exception) { } catch (e: Exception) {
@ -53,17 +56,17 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
// on the other we have parameters update process - it needs to be unified. Say you start the node, you don't have matching parameters, // on the other we have parameters update process - it needs to be unified. Say you start the node, you don't have matching parameters,
// you get them from network map, but you have to run the approval step. // you get them from network map, but you have to run the approval step.
if (signedParametersFromFile == null) { // Node joins for the first time. if (signedParametersFromFile == null) { // Node joins for the first time.
downloadParameters(trustRoot, advertisedParametersHash) downloadParameters(advertisedParametersHash)
} else if (signedParametersFromFile.raw.hash == advertisedParametersHash) { // Restarted with the same parameters. } else if (signedParametersFromFile.raw.hash == advertisedParametersHash) { // Restarted with the same parameters.
signedParametersFromFile.verifiedNetworkMapCert(trustRoot) signedParametersFromFile
} else { // Update case. } else { // Update case.
readParametersUpdate(advertisedParametersHash, signedParametersFromFile.raw.hash).verifiedNetworkMapCert(trustRoot) readParametersUpdate(advertisedParametersHash, signedParametersFromFile.raw.hash)
} }
} else { // No compatibility zone configured. Node should proceed with parameters from file. } else { // No compatibility zone configured. Node should proceed with parameters from file.
signedParametersFromFile?.verifiedNetworkMapCert(trustRoot) ?: throw IllegalArgumentException("Couldn't find network parameters file and compatibility zone wasn't configured/isn't reachable") signedParametersFromFile ?: throw IllegalArgumentException("Couldn't find network parameters file and compatibility zone wasn't configured/isn't reachable")
} }
logger.info("Loaded network parameters: $parameters") logger.info("Loaded network parameters: $parameters")
return parameters return NetworkParamsAndHash(parameters.verifiedNetworkMapCert(trustRoot), parameters.raw.hash)
} }
private fun readParametersUpdate(advertisedParametersHash: SecureHash, previousParametersHash: SecureHash): SignedNetworkParameters { private fun readParametersUpdate(advertisedParametersHash: SecureHash, previousParametersHash: SecureHash): SignedNetworkParameters {
@ -84,14 +87,13 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
} }
// Used only when node joins for the first time. // Used only when node joins for the first time.
private fun downloadParameters(trustRoot: X509Certificate, parametersHash: SecureHash): NetworkParameters { private fun downloadParameters(parametersHash: SecureHash): SignedNetworkParameters {
logger.info("No network-parameters file found. Expecting network parameters to be available from the network map.") logger.info("No network-parameters file found. Expecting network parameters to be available from the network map.")
val networkMapClient = checkNotNull(networkMapClient) { val networkMapClient = checkNotNull(networkMapClient) {
"Node hasn't been configured to connect to a network map from which to get the network parameters" "Node hasn't been configured to connect to a network map from which to get the network parameters"
} }
val signedParams = networkMapClient.getNetworkParameters(parametersHash) val signedParams = networkMapClient.getNetworkParameters(parametersHash)
val verifiedParams = signedParams.verifiedNetworkMapCert(trustRoot)
signedParams.serialize().open().copyTo(baseDirectory / NETWORK_PARAMS_FILE_NAME) signedParams.serialize().open().copyTo(baseDirectory / NETWORK_PARAMS_FILE_NAME)
return verifiedParams return signedParams
} }
} }

View File

@ -38,25 +38,25 @@ object NodeInfoSchemaV1 : MappedSchema(
class PersistentNodeInfo( class PersistentNodeInfo(
@Id @Id
@GeneratedValue @GeneratedValue
@Column(name = "node_info_id") @Column(name = "node_info_id", nullable = false)
var id: Int, var id: Int,
@Column(name = "node_info_hash", length = 64) @Column(name = "node_info_hash", length = 64, nullable = false)
val hash: String, val hash: String,
@Column(name = "addresses") @Column(name = "addresses", nullable = false)
@OneToMany(cascade = [(CascadeType.ALL)], orphanRemoval = true) @OneToMany(cascade = [(CascadeType.ALL)], orphanRemoval = true)
@JoinColumn(name = "node_info_id", foreignKey = ForeignKey(name = "FK__info_hosts__infos")) @JoinColumn(name = "node_info_id", foreignKey = ForeignKey(name = "FK__info_hosts__infos"))
val addresses: List<DBHostAndPort>, val addresses: List<DBHostAndPort>,
@Column(name = "legal_identities_certs") @Column(name = "legal_identities_certs", nullable = false)
@ManyToMany(cascade = [(CascadeType.ALL)]) @ManyToMany(cascade = [(CascadeType.ALL)])
@JoinTable(name = "node_link_nodeinfo_party", @JoinTable(name = "node_link_nodeinfo_party",
joinColumns = [(JoinColumn(name = "node_info_id", foreignKey = ForeignKey(name = "FK__link_nodeinfo_party__infos")))], joinColumns = [(JoinColumn(name = "node_info_id", foreignKey = ForeignKey(name = "FK__link_nodeinfo_party__infos")))],
inverseJoinColumns = [(JoinColumn(name = "party_name", foreignKey = ForeignKey(name = "FK__link_ni_p__info_p_cert")))]) inverseJoinColumns = [(JoinColumn(name = "party_name", foreignKey = ForeignKey(name = "FK__link_ni_p__info_p_cert")))])
val legalIdentitiesAndCerts: List<DBPartyAndCertificate>, val legalIdentitiesAndCerts: List<DBPartyAndCertificate>,
@Column(name = "platform_version") @Column(name = "platform_version", nullable = false)
val platformVersion: Int, val platformVersion: Int,
/** /**
@ -64,7 +64,7 @@ object NodeInfoSchemaV1 : MappedSchema(
* Not expected to be sequential, but later versions of the registration must have higher values * Not expected to be sequential, but later versions of the registration must have higher values
* Similar to the serial number on DNS records. * Similar to the serial number on DNS records.
*/ */
@Column(name = "serial") @Column(name = "serial", nullable = false)
val serial: Long val serial: Long
) : Serializable { ) : Serializable {
fun toNodeInfo(): NodeInfo { fun toNodeInfo(): NodeInfo {
@ -82,7 +82,7 @@ object NodeInfoSchemaV1 : MappedSchema(
data class DBHostAndPort( data class DBHostAndPort(
@Id @Id
@GeneratedValue @GeneratedValue
@Column(name = "hosts_id") @Column(name = "hosts_id", nullable = false)
var id: Int, var id: Int,
val host: String? = null, val host: String? = null,
val port: Int? = null val port: Int? = null
@ -108,11 +108,11 @@ 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_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "owning_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
val owningKeyHash: String, val owningKeyHash: String,
@Lob @Lob
@Column(name = "party_cert_binary") @Column(name = "party_cert_binary", nullable = false)
val partyCertBinary: ByteArray, val partyCertBinary: ByteArray,
val isMain: Boolean, val isMain: Boolean,

View File

@ -142,7 +142,7 @@ class NodeSchedulerService(private val clock: CordaClock,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}scheduled_states") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}scheduled_states")
class PersistentScheduledState( class PersistentScheduledState(
@EmbeddedId @EmbeddedId
var output: PersistentStateRef = PersistentStateRef(), var output: PersistentStateRef,
@Column(name = "scheduled_at", nullable = false) @Column(name = "scheduled_at", nullable = false)
var scheduledAt: Instant = Instant.now() var scheduledAt: Instant = Instant.now()

View File

@ -18,8 +18,8 @@ class PersistentScheduledFlowRepository(val database: CordaPersistence) : Schedu
} }
private fun toPersistentEntity(key: StateRef, value: ScheduledStateRef): NodeSchedulerService.PersistentScheduledState { private fun toPersistentEntity(key: StateRef, value: ScheduledStateRef): NodeSchedulerService.PersistentScheduledState {
return NodeSchedulerService.PersistentScheduledState().apply { val output = PersistentStateRef(key.txhash.toString(), key.index)
output = PersistentStateRef(key.txhash.toString(), key.index) return NodeSchedulerService.PersistentScheduledState(output).apply {
scheduledAt = value.scheduledAt scheduledAt = value.scheduledAt
} }
} }

View File

@ -88,11 +88,11 @@ class PersistentIdentityService(override val trustRoot: X509Certificate,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}identities") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}identities")
class PersistentIdentity( class PersistentIdentity(
@Id @Id
@Column(name = "pk_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "pk_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var publicKeyHash: String, var publicKeyHash: String = "",
@Lob @Lob
@Column(name = "identity_value") @Column(name = "identity_value", nullable = false)
var identity: ByteArray = EMPTY_BYTE_ARRAY var identity: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable ) : Serializable
@ -100,10 +100,10 @@ class PersistentIdentityService(override val trustRoot: X509Certificate,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}named_identities") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}named_identities")
class PersistentIdentityNames( class PersistentIdentityNames(
@Id @Id
@Column(name = "name", length = 128) @Column(name = "name", length = 128, nullable = false)
var name: String = "", var name: String = "",
@Column(name = "pk_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "pk_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var publicKeyHash: String = "" var publicKeyHash: String = ""
) : Serializable ) : Serializable

View File

@ -43,14 +43,14 @@ class PersistentKeyManagementService(val identityService: IdentityService,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}our_key_pairs") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}our_key_pairs")
class PersistentKey( class PersistentKey(
@Id @Id
@Column(name = "public_key_hash", length = MAX_HASH_HEX_SIZE) @Column(name = "public_key_hash", length = MAX_HASH_HEX_SIZE, nullable = false)
var publicKeyHash: String, var publicKeyHash: String,
@Lob @Lob
@Column(name = "public_key") @Column(name = "public_key", nullable = false)
var publicKey: ByteArray = EMPTY_BYTE_ARRAY, var publicKey: ByteArray = EMPTY_BYTE_ARRAY,
@Lob @Lob
@Column(name = "private_key") @Column(name = "private_key", nullable = false)
var privateKey: ByteArray = EMPTY_BYTE_ARRAY var privateKey: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable { ) : Serializable {
constructor(publicKey: PublicKey, privateKey: PrivateKey) constructor(publicKey: PublicKey, privateKey: PrivateKey)

View File

@ -150,16 +150,16 @@ class P2PMessageDeduplicator(private val database: CordaPersistence) {
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}message_ids") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}message_ids")
class ProcessedMessage( class ProcessedMessage(
@Id @Id
@Column(name = "message_id", length = 64) @Column(name = "message_id", length = 64, nullable = false)
var id: String = "", var id: String = "",
@Column(name = "insertion_time") @Column(name = "insertion_time", nullable = false)
var insertionTime: Instant = Instant.now(), var insertionTime: Instant = Instant.now(),
@Column(name = "sender", length = 64) @Column(name = "sender", length = 64, nullable = true)
var hash: String? = "", var hash: String? = "",
@Column(name = "sequence_number") @Column(name = "sequence_number", nullable = true)
var seqNo: Long? = null var seqNo: Long? = null
) : Serializable ) : Serializable

View File

@ -190,14 +190,14 @@ class P2PMessagingClient(val config: NodeConfiguration,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}message_retry") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}message_retry")
class RetryMessage( class RetryMessage(
@Id @Id
@Column(name = "message_id", length = 64) @Column(name = "message_id", length = 64, nullable = false)
var key: Long = 0, var key: Long = 0,
@Lob @Lob
@Column @Column(nullable = false)
var message: ByteArray = EMPTY_BYTE_ARRAY, var message: ByteArray = EMPTY_BYTE_ARRAY,
@Lob @Lob
@Column @Column(nullable = false)
var recipients: ByteArray = EMPTY_BYTE_ARRAY var recipients: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable ) : Serializable

View File

@ -191,7 +191,7 @@ The node will shutdown now.""")
val (update, signedNewNetParams) = requireNotNull(newNetworkParameters) { "Couldn't find parameters update for the hash: $parametersHash" } val (update, signedNewNetParams) = requireNotNull(newNetworkParameters) { "Couldn't find parameters update for the hash: $parametersHash" }
// We should check that we sign the right data structure hash. // We should check that we sign the right data structure hash.
val newNetParams = signedNewNetParams.verifiedNetworkMapCert(networkMapClient.trustedRoot) val newNetParams = signedNewNetParams.verifiedNetworkMapCert(networkMapClient.trustedRoot)
val newParametersHash = newNetParams.serialize().hash val newParametersHash = signedNewNetParams.raw.hash
if (parametersHash == newParametersHash) { if (parametersHash == newParametersHash) {
// The latest parameters have priority. // The latest parameters have priority.
signedNewNetParams.serialize() signedNewNetParams.serialize()

View File

@ -38,11 +38,11 @@ class DBCheckpointStorage : CheckpointStorage {
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}checkpoints") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}checkpoints")
class DBCheckpoint( class DBCheckpoint(
@Id @Id
@Column(name = "checkpoint_id", length = 64) @Column(name = "checkpoint_id", length = 64, nullable = false)
var checkpointId: String = "", var checkpointId: String = "",
@Lob @Lob
@Column(name = "checkpoint_value") @Column(name = "checkpoint_value", nullable = false)
var checkpoint: ByteArray = EMPTY_BYTE_ARRAY var checkpoint: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable ) : Serializable

View File

@ -42,10 +42,10 @@ class DBTransactionMappingStorage : StateMachineRecordedTransactionMappingStorag
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}transaction_mappings") @javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}transaction_mappings")
class DBTransactionMapping( class DBTransactionMapping(
@Id @Id
@Column(name = "tx_id", length = 64) @Column(name = "tx_id", length = 64, nullable = false)
var txId: String = "", var txId: String = "",
@Column(name = "state_machine_run_id", length = 36) @Column(name = "state_machine_run_id", length = 36, nullable = false)
var stateMachineRunId: String = "" var stateMachineRunId: String = ""
) : Serializable ) : Serializable

View File

@ -46,11 +46,11 @@ class DBTransactionStorage(cacheSizeBytes: Long) : WritableTransactionStorage, S
@Table(name = "${NODE_DATABASE_PREFIX}transactions") @Table(name = "${NODE_DATABASE_PREFIX}transactions")
class DBTransaction( class DBTransaction(
@Id @Id
@Column(name = "tx_id", length = 64) @Column(name = "tx_id", length = 64, nullable = false)
var txId: String = "", var txId: String = "",
@Lob @Lob
@Column(name = "transaction_value") @Column(name = "transaction_value", nullable = false)
var transaction: ByteArray = EMPTY_BYTE_ARRAY var transaction: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable ) : Serializable

View File

@ -89,24 +89,24 @@ class NodeAttachmentService(
@Table(name = "${NODE_DATABASE_PREFIX}attachments", indexes = [Index(name = "att_id_idx", columnList = "att_id")]) @Table(name = "${NODE_DATABASE_PREFIX}attachments", indexes = [Index(name = "att_id_idx", columnList = "att_id")])
class DBAttachment( class DBAttachment(
@Id @Id
@Column(name = "att_id") @Column(name = "att_id", nullable = false)
var attId: String, var attId: String,
@Column(name = "content") @Column(name = "content", nullable = false)
@Lob @Lob
var content: ByteArray, var content: ByteArray,
@Column(name = "insertion_date", nullable = false, updatable = false) @Column(name = "insertion_date", nullable = false, updatable = false)
var insertionDate: Instant = Instant.now(), var insertionDate: Instant = Instant.now(),
@Column(name = "uploader", updatable = false) @Column(name = "uploader", updatable = false, nullable = true)
var uploader: String? = null, var uploader: String? = null,
@Column(name = "filename", updatable = false) @Column(name = "filename", updatable = false, nullable = true)
var filename: String? = null, var filename: String? = null,
@ElementCollection @ElementCollection
@Column(name = "contract_class_name") @Column(name = "contract_class_name", nullable = false)
@CollectionTable(name = "node_attchments_contracts", joinColumns = [(JoinColumn(name = "att_id", referencedColumnName = "att_id"))], @CollectionTable(name = "node_attchments_contracts", joinColumns = [(JoinColumn(name = "att_id", referencedColumnName = "att_id"))],
foreignKey = ForeignKey(name = "FK__ctr_class__attachments")) foreignKey = ForeignKey(name = "FK__ctr_class__attachments"))
var contractClassNames: List<ContractClassName>? = null var contractClassNames: List<ContractClassName>? = null

View File

@ -40,10 +40,10 @@ class NodePropertiesPersistentStore(readPhysicalNodeId: () -> String, persistenc
@Table(name = "${NODE_DATABASE_PREFIX}properties") @Table(name = "${NODE_DATABASE_PREFIX}properties")
class DBNodeProperty( class DBNodeProperty(
@Id @Id
@Column(name = "property_key") @Column(name = "property_key", nullable = false)
val key: String = "", val key: String = "",
@Column(name = "property_value") @Column(name = "property_value", nullable = true)
var value: String? = "" var value: String? = ""
) : Serializable ) : Serializable
} }

View File

@ -116,8 +116,7 @@ class BFTNonValidatingNotaryService(
fromPersistentEntity = { fromPersistentEntity = {
//TODO null check will become obsolete after making DB/JPA columns not nullable //TODO null check will become obsolete after making DB/JPA columns not nullable
val txId = it.id.txId val txId = it.id.txId
?: throw IllegalStateException("DB returned null SecureHash transactionId") val index = it.id.index
val index = it.id.index ?: throw IllegalStateException("DB returned null SecureHash index")
Pair( Pair(
StateRef(txhash = SecureHash.parse(txId), index = index), StateRef(txhash = SecureHash.parse(txId), index = index),
SecureHash.parse(it.consumingTxHash) SecureHash.parse(it.consumingTxHash)

View File

@ -47,7 +47,7 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl
@EmbeddedId @EmbeddedId
val id: PersistentStateRef, val id: PersistentStateRef,
@Column(name = "consuming_transaction_id") @Column(name = "consuming_transaction_id", nullable = false)
val consumingTxHash: String val consumingTxHash: String
) : Serializable ) : Serializable
@ -57,19 +57,20 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl
class Request( class Request(
@Id @Id
@GeneratedValue @GeneratedValue
@Column(nullable = true)
val id: Int? = null, val id: Int? = null,
@Column(name = "consuming_transaction_id") @Column(name = "consuming_transaction_id", nullable = false)
val consumingTxHash: String, val consumingTxHash: String,
@Column(name = "requesting_party_name") @Column(name = "requesting_party_name", nullable = false)
var partyName: String, var partyName: String,
@Lob @Lob
@Column(name = "request_signature") @Column(name = "request_signature", nullable = false)
val requestSignature: ByteArray, val requestSignature: ByteArray,
@Column(name = "request_timestamp") @Column(name = "request_timestamp", nullable = false)
var requestDate: Instant var requestDate: Instant
) : Serializable ) : Serializable
@ -91,8 +92,7 @@ class PersistentUniquenessProvider(val clock: Clock) : UniquenessProvider, Singl
fromPersistentEntity = { fromPersistentEntity = {
//TODO null check will become obsolete after making DB/JPA columns not nullable //TODO null check will become obsolete after making DB/JPA columns not nullable
val txId = it.id.txId val txId = it.id.txId
?: throw IllegalStateException("DB returned null SecureHash transactionId") val index = it.id.index
val index = it.id.index ?: throw IllegalStateException("DB returned null SecureHash index")
Pair( Pair(
StateRef(txhash = SecureHash.parse(txId), index = index), StateRef(txhash = SecureHash.parse(txId), index = index),
SecureHash.parse(it.consumingTxHash) SecureHash.parse(it.consumingTxHash)

View File

@ -75,8 +75,7 @@ class RaftUniquenessProvider(
toPersistentEntityKey = { PersistentStateRef(it) }, toPersistentEntityKey = { PersistentStateRef(it) },
fromPersistentEntity = { fromPersistentEntity = {
val txId = it.id.txId val txId = it.id.txId
?: throw IllegalStateException("DB returned null SecureHash transactionId") val index = it.id.index
val index = it.id.index ?: throw IllegalStateException("DB returned null SecureHash index")
Pair( Pair(
StateRef(txhash = SecureHash.parse(txId), index = index), StateRef(txhash = SecureHash.parse(txId), index = index),
Pair(it.index, SecureHash.parse(it.value) as SecureHash)) Pair(it.index, SecureHash.parse(it.value) as SecureHash))
@ -101,9 +100,9 @@ class RaftUniquenessProvider(
class CommittedState( class CommittedState(
@EmbeddedId @EmbeddedId
val id: PersistentStateRef, val id: PersistentStateRef,
@Column(name = "consuming_transaction_id") @Column(name = "consuming_transaction_id", nullable = false)
var value: String = "", var value: String = "",
@Column(name = "raft_log_index") @Column(name = "raft_log_index", nullable = false)
var index: Long = 0 var index: Long = 0
) : Serializable ) : Serializable

View File

@ -28,11 +28,11 @@ class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsT
@Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades") @Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades")
class DBContractUpgrade( class DBContractUpgrade(
@Id @Id
@Column(name = "state_ref", length = 96) @Column(name = "state_ref", length = 96, nullable = false)
var stateRef: String = "", var stateRef: String = "",
/** refers to the UpgradedContract class name*/ /** refers to the UpgradedContract class name*/
@Column(name = "contract_class_name") @Column(name = "contract_class_name", nullable = false)
var upgradedContractClassName: String = "" var upgradedContractClassName: String = ""
) : Serializable ) : Serializable

View File

@ -47,19 +47,19 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
// TODO: create a distinct table to hold serialized state data (once DBTransactionStore is encrypted) // TODO: create a distinct table to hold serialized state data (once DBTransactionStore is encrypted)
/** refers to the X500Name of the notary a state is attached to */ /** refers to the X500Name of the notary a state is attached to */
@Column(name = "notary_name") @Column(name = "notary_name", nullable = false)
var notary: Party, var notary: Party,
/** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */ /** references a concrete ContractState that is [QueryableState] and has a [MappedSchema] */
@Column(name = "contract_state_class_name") @Column(name = "contract_state_class_name", nullable = false)
var contractStateClassName: String, var contractStateClassName: String,
/** state lifecycle: unconsumed, consumed */ /** state lifecycle: unconsumed, consumed */
@Column(name = "state_status") @Column(name = "state_status", nullable = false)
var stateStatus: Vault.StateStatus, var stateStatus: Vault.StateStatus,
/** refers to timestamp recorded upon entering UNCONSUMED state */ /** refers to timestamp recorded upon entering UNCONSUMED state */
@Column(name = "recorded_timestamp") @Column(name = "recorded_timestamp", nullable = false)
var recordedTime: Instant, var recordedTime: Instant,
/** refers to timestamp recorded upon entering CONSUMED state */ /** refers to timestamp recorded upon entering CONSUMED state */
@ -94,7 +94,7 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
/** /**
* Represents a [LinearState] [UniqueIdentifier] * Represents a [LinearState] [UniqueIdentifier]
*/ */
@Column(name = "external_id") @Column(name = "external_id", nullable = true)
var externalId: String?, var externalId: String?,
@Column(name = "uuid", nullable = false) @Column(name = "uuid", nullable = false)
@ -117,13 +117,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
@CollectionTable(name = "vault_fungible_states_parts", @CollectionTable(name = "vault_fungible_states_parts",
joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))], joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))],
foreignKey = ForeignKey(name = "FK__fung_st_parts__fung_st")) foreignKey = ForeignKey(name = "FK__fung_st_parts__fung_st"))
@Column(name = "participants") @Column(name = "participants", nullable = true)
var participants: MutableSet<AbstractParty>? = null, var participants: MutableSet<AbstractParty>? = null,
/** [OwnableState] attributes */ /** [OwnableState] attributes */
/** X500Name of owner party **/ /** X500Name of owner party **/
@Column(name = "owner_name") @Column(name = "owner_name", nullable = true)
var owner: AbstractParty, var owner: AbstractParty,
/** [FungibleAsset] attributes /** [FungibleAsset] attributes
@ -133,16 +133,16 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
*/ */
/** Amount attributes */ /** Amount attributes */
@Column(name = "quantity") @Column(name = "quantity", nullable = false)
var quantity: Long, var quantity: Long,
/** Issuer attributes */ /** Issuer attributes */
/** X500Name of issuer party **/ /** X500Name of issuer party **/
@Column(name = "issuer_name") @Column(name = "issuer_name", nullable = true)
var issuer: AbstractParty, var issuer: AbstractParty,
@Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE) @Column(name = "issuer_ref", length = MAX_ISSUER_REF_SIZE, nullable = false)
@Type(type = "corda-wrapper-binary") @Type(type = "corda-wrapper-binary")
var issuerRef: ByteArray var issuerRef: ByteArray
) : PersistentState() { ) : PersistentState() {
@ -159,13 +159,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
class VaultTxnNote( class VaultTxnNote(
@Id @Id
@GeneratedValue @GeneratedValue
@Column(name = "seq_no") @Column(name = "seq_no", nullable = false)
var seqNo: Int, var seqNo: Int,
@Column(name = "transaction_id", length = 64) @Column(name = "transaction_id", length = 64, nullable = false)
var txId: String, var txId: String,
@Column(name = "note") @Column(name = "note", nullable = false)
var note: String var note: String
) : Serializable { ) : Serializable {
constructor(txId: String, note: String) : this(0, txId, note) constructor(txId: String, note: String) : this(0, txId, note)

View File

@ -16,6 +16,8 @@ import net.corda.core.internal.createDirectories
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.exists import net.corda.core.internal.exists
import net.corda.core.internal.readObject import net.corda.core.internal.readObject
import net.corda.core.serialization.deserialize
import net.corda.core.utilities.days
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
import net.corda.node.internal.NetworkParametersReader import net.corda.node.internal.NetworkParametersReader
import net.corda.nodeapi.internal.network.* import net.corda.nodeapi.internal.network.*
@ -33,6 +35,7 @@ import java.net.URL
import java.nio.file.FileSystem import java.nio.file.FileSystem
import kotlin.test.assertEquals import kotlin.test.assertEquals
import kotlin.test.assertFalse import kotlin.test.assertFalse
import kotlin.test.assertNotNull
class NetworkParametersReaderTest { class NetworkParametersReaderTest {
@Rule @Rule
@ -83,4 +86,14 @@ class NetworkParametersReaderTest {
val parameters = NetworkParametersReader(DEV_ROOT_CA.certificate, networkMapClient, baseDirectory).networkParameters val parameters = NetworkParametersReader(DEV_ROOT_CA.certificate, networkMapClient, baseDirectory).networkParameters
assertThat(parameters).isEqualTo(fileParameters) assertThat(parameters).isEqualTo(fileParameters)
} }
@Test
fun `serialized parameters compatibility`() {
// Network parameters file from before eventHorizon extension
val inputStream = javaClass.classLoader.getResourceAsStream("network-compatibility/network-parameters")
assertNotNull(inputStream)
val inByteArray: ByteArray = inputStream.readBytes()
val parameters = inByteArray.deserialize<SignedNetworkParameters>()
assertThat(parameters.verified().eventHorizon).isEqualTo(Int.MAX_VALUE.days)
}
} }

View File

@ -130,7 +130,7 @@ abstract class EvolutionSerializer(
this.resultsIndex = it.index this.resultsIndex = it.index
} ?: if (!it.value.type.isMarkedNullable) { } ?: if (!it.value.type.isMarkedNullable) {
throw NotSerializableException( throw NotSerializableException(
"New parameter ${it.value.name} is mandatory, should be nullable for evolution to worK") "New parameter ${it.value.name} is mandatory, should be nullable for evolution to work")
} }
} }
return EvolutionSerializerViaConstructor(new.type, factory, readersAsSerialized, constructor, constructorArgs) return EvolutionSerializerViaConstructor(new.type, factory, readersAsSerialized, constructor, constructorArgs)

View File

@ -48,7 +48,7 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
/** /**
* UniqueIdentifier * UniqueIdentifier
*/ */
@Column(name = "external_id") @Column(name = "external_id", nullable = true)
var externalId: String?, var externalId: String?,
@Column(name = "uuid", nullable = false) @Column(name = "uuid", nullable = false)
@ -58,16 +58,16 @@ object DummyLinearStateSchemaV1 : MappedSchema(schemaFamily = DummyLinearStateSc
/** /**
* Dummy attributes * Dummy attributes
*/ */
@Column(name = "linear_string") @Column(name = "linear_string", nullable = false)
var linearString: String, var linearString: String,
@Column(name = "linear_number") @Column(name = "linear_number", nullable = false)
var linearNumber: Long, var linearNumber: Long,
@Column(name = "linear_timestamp") @Column(name = "linear_timestamp", nullable = false)
var linearTimestamp: Instant, var linearTimestamp: Instant,
@Column(name = "linear_boolean") @Column(name = "linear_boolean", nullable = false)
var linearBoolean: Boolean var linearBoolean: Boolean
) : PersistentState() ) : PersistentState()
} }

View File

@ -34,13 +34,13 @@ object DummyLinearStateSchemaV2 : MappedSchema(schemaFamily = DummyLinearStateSc
@CollectionTable(name = "dummy_linear_states_v2_parts", joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))]) @CollectionTable(name = "dummy_linear_states_v2_parts", joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))])
override var participants: MutableSet<AbstractParty>? = null, override var participants: MutableSet<AbstractParty>? = null,
@Column(name = "linear_string") var linearString: String, @Column(name = "linear_string", nullable = false) var linearString: String,
@Column(name = "linear_number") var linearNumber: Long, @Column(name = "linear_number", nullable = false) var linearNumber: Long,
@Column(name = "linear_timestamp") var linearTimestamp: java.time.Instant, @Column(name = "linear_timestamp", nullable = false) var linearTimestamp: java.time.Instant,
@Column(name = "linear_boolean") var linearBoolean: Boolean, @Column(name = "linear_boolean", nullable = false) var linearBoolean: Boolean,
@Transient @Transient
val uid: UniqueIdentifier val uid: UniqueIdentifier