Merge pull request #883 from corda/merges/os-2017-05-29

OS merge up to 2017-05-28
This commit is contained in:
szymonsztuka
2018-05-29 12:53:56 +01:00
committed by GitHub
50 changed files with 255 additions and 164 deletions

View File

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

View File

@ -305,8 +305,8 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
val identityService = makeIdentityService(identity.certificate)
networkMapClient = configuration.networkServices?.let { NetworkMapClient(it.networkMapURL, identityService.trustRoot) }
val networkParameters = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory).networkParameters
val networkParameteresReader = NetworkParametersReader(identityService.trustRoot, networkMapClient, configuration.baseDirectory)
val networkParameters = networkParameteresReader.networkParameters
check(networkParameters.minimumPlatformVersion <= versionInfo.platformVersion) {
"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,
NodeInfoWatcher(configuration.baseDirectory, getRxIoScheduler(), Duration.ofMillis(configuration.additionalNodeInfoPollingFrequencyMsec)),
networkMapClient,
networkParameters.serialize().hash,
networkParameteresReader.hash,
services.myInfo.serialize().hash,
configuration.baseDirectory,
configuration.extraNetworkMapKeys)

View File

@ -31,11 +31,14 @@ class NetworkParametersReader(private val trustRoot: X509Certificate,
private val logger = contextLogger()
}
private data class NetworkParamsAndHash(val networkParameters: NetworkParameters, val hash: SecureHash)
private val networkParamsFile = baseDirectory / NETWORK_PARAMS_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 {
networkMapClient?.getNetworkMap()?.payload?.networkParameterHash
} 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,
// you get them from network map, but you have to run the approval step.
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.
signedParametersFromFile.verifiedNetworkMapCert(trustRoot)
signedParametersFromFile
} 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.
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")
return parameters
return NetworkParamsAndHash(parameters.verifiedNetworkMapCert(trustRoot), parameters.raw.hash)
}
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.
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.")
val networkMapClient = checkNotNull(networkMapClient) {
"Node hasn't been configured to connect to a network map from which to get the network parameters"
}
val signedParams = networkMapClient.getNetworkParameters(parametersHash)
val verifiedParams = signedParams.verifiedNetworkMapCert(trustRoot)
signedParams.serialize().open().copyTo(baseDirectory / NETWORK_PARAMS_FILE_NAME)
return verifiedParams
return signedParams
}
}

View File

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

View File

@ -142,7 +142,7 @@ class NodeSchedulerService(private val clock: CordaClock,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}scheduled_states")
class PersistentScheduledState(
@EmbeddedId
var output: PersistentStateRef = PersistentStateRef(),
var output: PersistentStateRef,
@Column(name = "scheduled_at", nullable = false)
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 {
return NodeSchedulerService.PersistentScheduledState().apply {
output = PersistentStateRef(key.txhash.toString(), key.index)
val output = PersistentStateRef(key.txhash.toString(), key.index)
return NodeSchedulerService.PersistentScheduledState(output).apply {
scheduledAt = value.scheduledAt
}
}

View File

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

View File

@ -43,14 +43,14 @@ class PersistentKeyManagementService(val identityService: IdentityService,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}our_key_pairs")
class PersistentKey(
@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,
@Lob
@Column(name = "public_key")
@Column(name = "public_key", nullable = false)
var publicKey: ByteArray = EMPTY_BYTE_ARRAY,
@Lob
@Column(name = "private_key")
@Column(name = "private_key", nullable = false)
var privateKey: ByteArray = EMPTY_BYTE_ARRAY
) : Serializable {
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")
class ProcessedMessage(
@Id
@Column(name = "message_id", length = 64)
@Column(name = "message_id", length = 64, nullable = false)
var id: String = "",
@Column(name = "insertion_time")
@Column(name = "insertion_time", nullable = false)
var insertionTime: Instant = Instant.now(),
@Column(name = "sender", length = 64)
@Column(name = "sender", length = 64, nullable = true)
var hash: String? = "",
@Column(name = "sequence_number")
@Column(name = "sequence_number", nullable = true)
var seqNo: Long? = null
) : Serializable

View File

@ -190,14 +190,14 @@ class P2PMessagingClient(val config: NodeConfiguration,
@javax.persistence.Table(name = "${NODE_DATABASE_PREFIX}message_retry")
class RetryMessage(
@Id
@Column(name = "message_id", length = 64)
@Column(name = "message_id", length = 64, nullable = false)
var key: Long = 0,
@Lob
@Column
@Column(nullable = false)
var message: ByteArray = EMPTY_BYTE_ARRAY,
@Lob
@Column
@Column(nullable = false)
var recipients: ByteArray = EMPTY_BYTE_ARRAY
) : 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" }
// We should check that we sign the right data structure hash.
val newNetParams = signedNewNetParams.verifiedNetworkMapCert(networkMapClient.trustedRoot)
val newParametersHash = newNetParams.serialize().hash
val newParametersHash = signedNewNetParams.raw.hash
if (parametersHash == newParametersHash) {
// The latest parameters have priority.
signedNewNetParams.serialize()

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -28,11 +28,11 @@ class ContractUpgradeServiceImpl : ContractUpgradeService, SingletonSerializeAsT
@Table(name = "${NODE_DATABASE_PREFIX}contract_upgrades")
class DBContractUpgrade(
@Id
@Column(name = "state_ref", length = 96)
@Column(name = "state_ref", length = 96, nullable = false)
var stateRef: String = "",
/** refers to the UpgradedContract class name*/
@Column(name = "contract_class_name")
@Column(name = "contract_class_name", nullable = false)
var upgradedContractClassName: String = ""
) : 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)
/** 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,
/** 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,
/** state lifecycle: unconsumed, consumed */
@Column(name = "state_status")
@Column(name = "state_status", nullable = false)
var stateStatus: Vault.StateStatus,
/** refers to timestamp recorded upon entering UNCONSUMED state */
@Column(name = "recorded_timestamp")
@Column(name = "recorded_timestamp", nullable = false)
var recordedTime: Instant,
/** refers to timestamp recorded upon entering CONSUMED state */
@ -94,7 +94,7 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
/**
* Represents a [LinearState] [UniqueIdentifier]
*/
@Column(name = "external_id")
@Column(name = "external_id", nullable = true)
var externalId: String?,
@Column(name = "uuid", nullable = false)
@ -117,13 +117,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
@CollectionTable(name = "vault_fungible_states_parts",
joinColumns = [(JoinColumn(name = "output_index", referencedColumnName = "output_index")), (JoinColumn(name = "transaction_id", referencedColumnName = "transaction_id"))],
foreignKey = ForeignKey(name = "FK__fung_st_parts__fung_st"))
@Column(name = "participants")
@Column(name = "participants", nullable = true)
var participants: MutableSet<AbstractParty>? = null,
/** [OwnableState] attributes */
/** X500Name of owner party **/
@Column(name = "owner_name")
@Column(name = "owner_name", nullable = true)
var owner: AbstractParty,
/** [FungibleAsset] attributes
@ -133,16 +133,16 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
*/
/** Amount attributes */
@Column(name = "quantity")
@Column(name = "quantity", nullable = false)
var quantity: Long,
/** Issuer attributes */
/** X500Name of issuer party **/
@Column(name = "issuer_name")
@Column(name = "issuer_name", nullable = true)
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")
var issuerRef: ByteArray
) : PersistentState() {
@ -159,13 +159,13 @@ object VaultSchemaV1 : MappedSchema(schemaFamily = VaultSchema.javaClass, versio
class VaultTxnNote(
@Id
@GeneratedValue
@Column(name = "seq_no")
@Column(name = "seq_no", nullable = false)
var seqNo: Int,
@Column(name = "transaction_id", length = 64)
@Column(name = "transaction_id", length = 64, nullable = false)
var txId: String,
@Column(name = "note")
@Column(name = "note", nullable = false)
var note: String
) : Serializable {
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.exists
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.node.internal.NetworkParametersReader
import net.corda.nodeapi.internal.network.*
@ -33,6 +35,7 @@ import java.net.URL
import java.nio.file.FileSystem
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
class NetworkParametersReaderTest {
@Rule
@ -83,4 +86,14 @@ class NetworkParametersReaderTest {
val parameters = NetworkParametersReader(DEV_ROOT_CA.certificate, networkMapClient, baseDirectory).networkParameters
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)
}
}