ENT-10289 Ensure Sender and Receiver Distribution records share the same timestamp (#7437)

This commit is contained in:
Jose Coll 2023-07-20 09:55:44 +01:00 committed by GitHub
parent 48213b5f8c
commit 7d1d2297e7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 13 additions and 8 deletions

View File

@ -141,8 +141,9 @@ class DBTransactionStorageLedgerRecovery(private val database: CordaPersistence,
override fun addSenderTransactionRecoveryMetadata(id: SecureHash, metadata: TransactionMetadata): ByteArray {
return database.transaction {
metadata.distributionList.peersToStatesToRecord.map { (peer, _) ->
val senderDistributionRecord = DBSenderDistributionRecord(PersistentKey(Key(clock.instant())),
val senderRecordingTimestamp = clock.instant()
metadata.distributionList.peersToStatesToRecord.forEach { (peer, _) ->
val senderDistributionRecord = DBSenderDistributionRecord(PersistentKey(Key(senderRecordingTimestamp)),
id.toString(),
partyInfoCache.getPartyIdByCordaX500Name(peer),
metadata.distributionList.senderStatesToRecord)
@ -150,15 +151,16 @@ class DBTransactionStorageLedgerRecovery(private val database: CordaPersistence,
}
val hashedPeersToStatesToRecord = metadata.distributionList.peersToStatesToRecord.map { (peer, statesToRecord) ->
partyInfoCache.getPartyIdByCordaX500Name(peer) to statesToRecord }.toMap()
val hashedDistributionList = HashedDistributionList(metadata.distributionList.senderStatesToRecord, hashedPeersToStatesToRecord)
val hashedDistributionList = HashedDistributionList(metadata.distributionList.senderStatesToRecord, hashedPeersToStatesToRecord, senderRecordingTimestamp)
cryptoService.encrypt(hashedDistributionList.serialize())
}
}
override fun addReceiverTransactionRecoveryMetadata(id: SecureHash, sender: CordaX500Name, receiver: CordaX500Name, receiverStatesToRecord: StatesToRecord, encryptedDistributionList: ByteArray) {
val senderRecordedTimestamp = HashedDistributionList.deserialize(cryptoService.decrypt(encryptedDistributionList)).senderRecordedTimestamp
database.transaction {
val receiverDistributionRecord =
DBReceiverDistributionRecord(Key(clock.instant()),
DBReceiverDistributionRecord(Key(senderRecordedTimestamp),
id,
partyInfoCache.getPartyIdByCordaX500Name(sender),
encryptedDistributionList,
@ -320,7 +322,8 @@ enum class DistributionRecordType {
@CordaSerializable
data class HashedDistributionList(
val senderStatesToRecord: StatesToRecord,
val peerHashToStatesToRecord: Map<Long, StatesToRecord>
val peerHashToStatesToRecord: Map<Long, StatesToRecord>,
val senderRecordedTimestamp: Instant
) {
fun serialize(): ByteArray {
val baos = ByteArrayOutputStream()
@ -333,6 +336,7 @@ data class HashedDistributionList(
out.writeLong(entry.key)
out.writeByte(entry.value.ordinal)
}
out.writeLong(senderRecordedTimestamp.toEpochMilli())
out.flush()
return baos.toByteArray()
}
@ -349,7 +353,8 @@ data class HashedDistributionList(
repeat (numPeerHashToStatesToRecords) {
peerHashToStatesToRecord[input.readLong()] = StatesToRecord.values()[input.readByte().toInt()]
}
return HashedDistributionList(senderStatesToRecord, peerHashToStatesToRecord)
val senderRecordedTimestamp = Instant.ofEpochMilli(input.readLong())
return HashedDistributionList(senderStatesToRecord, peerHashToStatesToRecord, senderRecordedTimestamp)
}
}
}

View File

@ -279,7 +279,7 @@ class DBTransactionStorageLedgerRecoveryTests {
@Test(timeout = 300_000)
fun `test lightweight serialization and deserialization of hashed distribution list payload`() {
val dl = HashedDistributionList(ALL_VISIBLE,
mapOf(BOB.name.hashCode().toLong() to NONE, CHARLIE_NAME.hashCode().toLong() to ONLY_RELEVANT))
mapOf(BOB.name.hashCode().toLong() to NONE, CHARLIE_NAME.hashCode().toLong() to ONLY_RELEVANT), now())
assertEquals(dl, dl.serialize().let { HashedDistributionList.deserialize(it) })
}
@ -373,7 +373,7 @@ class DBTransactionStorageLedgerRecoveryTests {
private fun DistributionList.toWire(cryptoService: CryptoService = MockCryptoService(emptyMap())): ByteArray {
val hashedPeersToStatesToRecord = this.peersToStatesToRecord.map { (peer, statesToRecord) ->
partyInfoCache.getPartyIdByCordaX500Name(peer) to statesToRecord }.toMap()
val hashedDistributionList = HashedDistributionList(this.senderStatesToRecord, hashedPeersToStatesToRecord)
val hashedDistributionList = HashedDistributionList(this.senderStatesToRecord, hashedPeersToStatesToRecord, now())
return cryptoService.encrypt(hashedDistributionList.serialize())
}
}