mirror of
https://github.com/corda/corda.git
synced 2025-06-19 15:43:52 +00:00
Rename Timestamp to TimeWindow (#706)
Rename Timestamp to TimeWindow + refactoring
This commit is contained in:
committed by
GitHub
parent
1aae41214f
commit
9f2b44f8f7
@ -509,20 +509,20 @@ abstract class AbstractNode(open val configuration: NodeConfiguration,
|
||||
}
|
||||
|
||||
open protected fun makeNotaryService(type: ServiceType, tokenizableServices: MutableList<Any>) {
|
||||
val timestampChecker = TimestampChecker(platformClock, 30.seconds)
|
||||
val timeWindowChecker = TimeWindowChecker(platformClock, 30.seconds)
|
||||
val uniquenessProvider = makeUniquenessProvider(type)
|
||||
tokenizableServices.add(uniquenessProvider)
|
||||
|
||||
val notaryService = when (type) {
|
||||
SimpleNotaryService.type -> SimpleNotaryService(timestampChecker, uniquenessProvider)
|
||||
ValidatingNotaryService.type -> ValidatingNotaryService(timestampChecker, uniquenessProvider)
|
||||
RaftNonValidatingNotaryService.type -> RaftNonValidatingNotaryService(timestampChecker, uniquenessProvider as RaftUniquenessProvider)
|
||||
RaftValidatingNotaryService.type -> RaftValidatingNotaryService(timestampChecker, uniquenessProvider as RaftUniquenessProvider)
|
||||
SimpleNotaryService.type -> SimpleNotaryService(timeWindowChecker, uniquenessProvider)
|
||||
ValidatingNotaryService.type -> ValidatingNotaryService(timeWindowChecker, uniquenessProvider)
|
||||
RaftNonValidatingNotaryService.type -> RaftNonValidatingNotaryService(timeWindowChecker, uniquenessProvider as RaftUniquenessProvider)
|
||||
RaftValidatingNotaryService.type -> RaftValidatingNotaryService(timeWindowChecker, uniquenessProvider as RaftUniquenessProvider)
|
||||
BFTNonValidatingNotaryService.type -> with(configuration as FullNodeConfiguration) {
|
||||
val replicaId = bftReplicaId ?: throw IllegalArgumentException("bftReplicaId value must be specified in the configuration")
|
||||
BFTSMaRtConfig(notaryClusterAddresses).use { config ->
|
||||
val client = BFTSMaRt.Client(config, replicaId).also { tokenizableServices += it } // (Ab)use replicaId for clientId.
|
||||
BFTNonValidatingNotaryService(config, services, timestampChecker, replicaId, database, client)
|
||||
BFTNonValidatingNotaryService(config, services, timeWindowChecker, replicaId, database, client)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
@ -2,9 +2,9 @@ package net.corda.node.services.transactions
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.serialization.deserialize
|
||||
import net.corda.core.serialization.serialize
|
||||
import net.corda.core.transactions.FilteredTransaction
|
||||
@ -20,11 +20,11 @@ import kotlin.concurrent.thread
|
||||
/**
|
||||
* A non-validating notary service operated by a group of parties that don't necessarily trust each other.
|
||||
*
|
||||
* A transaction is notarised when the consensus is reached by the cluster on its uniqueness, and timestamp validity.
|
||||
* A transaction is notarised when the consensus is reached by the cluster on its uniqueness, and time-window validity.
|
||||
*/
|
||||
class BFTNonValidatingNotaryService(config: BFTSMaRtConfig,
|
||||
services: ServiceHubInternal,
|
||||
timestampChecker: TimestampChecker,
|
||||
timeWindowChecker: TimeWindowChecker,
|
||||
serverId: Int,
|
||||
db: Database,
|
||||
private val client: BFTSMaRt.Client) : NotaryService {
|
||||
@ -32,7 +32,7 @@ class BFTNonValidatingNotaryService(config: BFTSMaRtConfig,
|
||||
val configHandle = config.handle()
|
||||
thread(name = "BFTSmartServer-$serverId", isDaemon = true) {
|
||||
configHandle.use {
|
||||
Server(configHandle.path, serverId, db, "bft_smart_notary_committed_states", services, timestampChecker)
|
||||
Server(configHandle.path, serverId, db, "bft_smart_notary_committed_states", services, timeWindowChecker)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -72,7 +72,7 @@ class BFTNonValidatingNotaryService(config: BFTSMaRtConfig,
|
||||
db: Database,
|
||||
tableName: String,
|
||||
services: ServiceHubInternal,
|
||||
timestampChecker: TimestampChecker) : BFTSMaRt.Server(configHome, id, db, tableName, services, timestampChecker) {
|
||||
timeWindowChecker: TimeWindowChecker) : BFTSMaRt.Server(configHome, id, db, tableName, services, timeWindowChecker) {
|
||||
|
||||
override fun executeCommand(command: ByteArray): ByteArray {
|
||||
val request = command.deserialize<BFTSMaRt.CommitRequest>()
|
||||
@ -86,7 +86,7 @@ class BFTNonValidatingNotaryService(config: BFTSMaRtConfig,
|
||||
val id = ftx.rootHash
|
||||
val inputs = ftx.filteredLeaves.inputs
|
||||
|
||||
validateTimestamp(ftx.filteredLeaves.timestamp)
|
||||
validateTimeWindow(ftx.filteredLeaves.timeWindow)
|
||||
commitInputStates(inputs, id, callerIdentity)
|
||||
|
||||
log.debug { "Inputs committed successfully, signing $id" }
|
||||
|
@ -8,13 +8,13 @@ import bftsmart.tom.server.defaultservices.DefaultRecoverable
|
||||
import bftsmart.tom.server.defaultservices.DefaultReplier
|
||||
import bftsmart.tom.util.Extractor
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.contracts.Timestamp
|
||||
import net.corda.core.contracts.TimeWindow
|
||||
import net.corda.core.crypto.DigitalSignature
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.crypto.SignedData
|
||||
import net.corda.core.crypto.sign
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
@ -147,7 +147,7 @@ object BFTSMaRt {
|
||||
val db: Database,
|
||||
tableName: String,
|
||||
val services: ServiceHubInternal,
|
||||
val timestampChecker: TimestampChecker) : DefaultRecoverable() {
|
||||
val timeWindowChecker: TimeWindowChecker) : DefaultRecoverable() {
|
||||
companion object {
|
||||
private val log = loggerFor<Server>()
|
||||
}
|
||||
@ -174,7 +174,7 @@ object BFTSMaRt {
|
||||
|
||||
/**
|
||||
* Implement logic to execute the command and commit the transaction to the log.
|
||||
* Helper methods are provided for transaction processing: [commitInputStates], [validateTimestamp], and [sign].
|
||||
* Helper methods are provided for transaction processing: [commitInputStates], [validateTimeWindow], and [sign].
|
||||
*/
|
||||
abstract fun executeCommand(command: ByteArray): ByteArray?
|
||||
|
||||
@ -201,9 +201,9 @@ object BFTSMaRt {
|
||||
}
|
||||
}
|
||||
|
||||
protected fun validateTimestamp(t: Timestamp?) {
|
||||
if (t != null && !timestampChecker.isValid(t))
|
||||
throw NotaryException(NotaryError.TimestampInvalid)
|
||||
protected fun validateTimeWindow(t: TimeWindow?) {
|
||||
if (t != null && !timeWindowChecker.isValid(t))
|
||||
throw NotaryException(NotaryError.TimeWindowInvalid)
|
||||
}
|
||||
|
||||
protected fun sign(bytes: ByteArray): DigitalSignature.WithKey {
|
||||
|
@ -2,7 +2,7 @@ package net.corda.node.services.transactions
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
import net.corda.core.transactions.FilteredTransaction
|
||||
import net.corda.core.utilities.unwrap
|
||||
@ -10,8 +10,8 @@ import net.corda.flows.NotaryFlow
|
||||
import net.corda.flows.TransactionParts
|
||||
|
||||
class NonValidatingNotaryFlow(otherSide: Party,
|
||||
timestampChecker: TimestampChecker,
|
||||
uniquenessProvider: UniquenessProvider) : NotaryFlow.Service(otherSide, timestampChecker, uniquenessProvider) {
|
||||
timeWindowChecker: TimeWindowChecker,
|
||||
uniquenessProvider: UniquenessProvider) : NotaryFlow.Service(otherSide, timeWindowChecker, uniquenessProvider) {
|
||||
/**
|
||||
* The received transaction is not checked for contract-validity, as that would require fully
|
||||
* resolving it into a [TransactionForVerification], for which the caller would have to reveal the whole transaction
|
||||
@ -26,6 +26,6 @@ class NonValidatingNotaryFlow(otherSide: Party,
|
||||
it.verify()
|
||||
it
|
||||
}
|
||||
return TransactionParts(ftx.rootHash, ftx.filteredLeaves.inputs, ftx.filteredLeaves.timestamp)
|
||||
return TransactionParts(ftx.rootHash, ftx.filteredLeaves.inputs, ftx.filteredLeaves.timeWindow)
|
||||
}
|
||||
}
|
@ -2,16 +2,16 @@ package net.corda.node.services.transactions
|
||||
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
|
||||
/** A non-validating notary service operated by a group of mutually trusting parties, uses the Raft algorithm to achieve consensus. */
|
||||
class RaftNonValidatingNotaryService(val timestampChecker: TimestampChecker,
|
||||
class RaftNonValidatingNotaryService(val timeWindowChecker: TimeWindowChecker,
|
||||
val uniquenessProvider: RaftUniquenessProvider) : NotaryService {
|
||||
companion object {
|
||||
val type = SimpleNotaryService.type.getSubType("raft")
|
||||
}
|
||||
|
||||
override val serviceFlowFactory: (Party, Int) -> FlowLogic<Void?> = { otherParty, _ ->
|
||||
NonValidatingNotaryFlow(otherParty, timestampChecker, uniquenessProvider)
|
||||
NonValidatingNotaryFlow(otherParty, timeWindowChecker, uniquenessProvider)
|
||||
}
|
||||
}
|
||||
|
@ -2,16 +2,16 @@ package net.corda.node.services.transactions
|
||||
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
|
||||
/** A validating notary service operated by a group of mutually trusting parties, uses the Raft algorithm to achieve consensus. */
|
||||
class RaftValidatingNotaryService(val timestampChecker: TimestampChecker,
|
||||
class RaftValidatingNotaryService(val timeWindowChecker: TimeWindowChecker,
|
||||
val uniquenessProvider: RaftUniquenessProvider) : NotaryService {
|
||||
companion object {
|
||||
val type = ValidatingNotaryService.type.getSubType("raft")
|
||||
}
|
||||
|
||||
override val serviceFlowFactory: (Party, Int) -> FlowLogic<Void?> = { otherParty, _ ->
|
||||
ValidatingNotaryFlow(otherParty, timestampChecker, uniquenessProvider)
|
||||
ValidatingNotaryFlow(otherParty, timeWindowChecker, uniquenessProvider)
|
||||
}
|
||||
}
|
||||
|
@ -3,17 +3,17 @@ package net.corda.node.services.transactions
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
|
||||
/** A simple Notary service that does not perform transaction validation */
|
||||
class SimpleNotaryService(val timestampChecker: TimestampChecker,
|
||||
class SimpleNotaryService(val timeWindowChecker: TimeWindowChecker,
|
||||
val uniquenessProvider: UniquenessProvider) : NotaryService {
|
||||
companion object {
|
||||
val type = ServiceType.notary.getSubType("simple")
|
||||
}
|
||||
|
||||
override val serviceFlowFactory: (Party, Int) -> FlowLogic<Void?> = { otherParty, _ ->
|
||||
NonValidatingNotaryFlow(otherParty, timestampChecker, uniquenessProvider)
|
||||
NonValidatingNotaryFlow(otherParty, timeWindowChecker, uniquenessProvider)
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ package net.corda.node.services.transactions
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.TransactionVerificationException
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.transactions.WireTransaction
|
||||
@ -18,9 +18,9 @@ import java.security.SignatureException
|
||||
* indeed valid.
|
||||
*/
|
||||
class ValidatingNotaryFlow(otherSide: Party,
|
||||
timestampChecker: TimestampChecker,
|
||||
timeWindowChecker: TimeWindowChecker,
|
||||
uniquenessProvider: UniquenessProvider) :
|
||||
NotaryFlow.Service(otherSide, timestampChecker, uniquenessProvider) {
|
||||
NotaryFlow.Service(otherSide, timeWindowChecker, uniquenessProvider) {
|
||||
/**
|
||||
* The received transaction is checked for contract-validity, which requires fully resolving it into a
|
||||
* [TransactionForVerification], for which the caller also has to to reveal the whole transaction
|
||||
@ -32,7 +32,7 @@ class ValidatingNotaryFlow(otherSide: Party,
|
||||
checkSignatures(stx)
|
||||
val wtx = stx.tx
|
||||
validateTransaction(wtx)
|
||||
return TransactionParts(wtx.id, wtx.inputs, wtx.timestamp)
|
||||
return TransactionParts(wtx.id, wtx.inputs, wtx.timeWindow)
|
||||
}
|
||||
|
||||
private fun checkSignatures(stx: SignedTransaction) {
|
||||
|
@ -3,17 +3,17 @@ package net.corda.node.services.transactions
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.services.ServiceType
|
||||
import net.corda.core.node.services.TimestampChecker
|
||||
import net.corda.core.node.services.TimeWindowChecker
|
||||
import net.corda.core.node.services.UniquenessProvider
|
||||
|
||||
/** A Notary service that validates the transaction chain of the submitted transaction before committing it */
|
||||
class ValidatingNotaryService(val timestampChecker: TimestampChecker,
|
||||
class ValidatingNotaryService(val timeWindowChecker: TimeWindowChecker,
|
||||
val uniquenessProvider: UniquenessProvider) : NotaryService {
|
||||
companion object {
|
||||
val type = ServiceType.notary.getSubType("validating")
|
||||
}
|
||||
|
||||
override val serviceFlowFactory: (Party, Int) -> FlowLogic<Void?> = { otherParty, _ ->
|
||||
ValidatingNotaryFlow(otherParty, timestampChecker, uniquenessProvider)
|
||||
ValidatingNotaryFlow(otherParty, timeWindowChecker, uniquenessProvider)
|
||||
}
|
||||
}
|
||||
|
@ -474,7 +474,7 @@ class TwoPartyTradeFlowTests {
|
||||
@Test
|
||||
fun `dependency with error on seller side`() {
|
||||
ledger {
|
||||
runWithError(false, true, "must be timestamped")
|
||||
runWithError(false, true, "Issuances must have a time-window")
|
||||
}
|
||||
}
|
||||
|
||||
@ -602,7 +602,7 @@ class TwoPartyTradeFlowTests {
|
||||
// Put a broken command on so at least a signature is created
|
||||
command(issuer.owningKey) { Cash.Commands.Move() }
|
||||
}
|
||||
timestamp(TEST_TX_TIME)
|
||||
timeWindow(TEST_TX_TIME)
|
||||
if (withError) {
|
||||
this.fails()
|
||||
} else {
|
||||
@ -642,7 +642,7 @@ class TwoPartyTradeFlowTests {
|
||||
}
|
||||
command(MEGA_CORP_PUBKEY) { CommercialPaper.Commands.Issue() }
|
||||
if (!withError)
|
||||
timestamp(time = TEST_TX_TIME)
|
||||
timeWindow(time = TEST_TX_TIME)
|
||||
if (attachmentID != null)
|
||||
attachment(attachmentID)
|
||||
if (withError) {
|
||||
|
@ -170,7 +170,7 @@ fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode, notaryNode: A
|
||||
|
||||
fun issueInvalidState(node: AbstractNode, notary: Party): StateAndRef<*> {
|
||||
val tx = DummyContract.generateInitial(Random().nextInt(), notary, node.info.legalIdentity.ref(0))
|
||||
tx.setTime(Instant.now(), 30.seconds)
|
||||
tx.addTimeWindow(Instant.now(), 30.seconds)
|
||||
val stx = node.services.signInitialTransaction(tx)
|
||||
node.services.recordTransactions(listOf(stx))
|
||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||
|
@ -167,7 +167,7 @@ class RequeryConfigurationTest {
|
||||
notary = DUMMY_NOTARY,
|
||||
signers = emptyList(),
|
||||
type = TransactionType.General,
|
||||
timestamp = null
|
||||
timeWindow = null
|
||||
)
|
||||
return SignedTransaction(wtx.serialized, listOf(DigitalSignature.WithKey(NullPublicKey, ByteArray(1))))
|
||||
}
|
||||
|
@ -154,7 +154,7 @@ class DBTransactionStorageTests {
|
||||
notary = DUMMY_NOTARY,
|
||||
signers = emptyList(),
|
||||
type = TransactionType.General,
|
||||
timestamp = null
|
||||
timeWindow = null
|
||||
)
|
||||
return SignedTransaction(wtx.serialized, listOf(DigitalSignature.WithKey(NullPublicKey, ByteArray(1))))
|
||||
}
|
||||
|
@ -39,11 +39,11 @@ class NotaryServiceTests {
|
||||
net.runNetwork() // Clear network map registration messages
|
||||
}
|
||||
|
||||
@Test fun `should sign a unique transaction with a valid timestamp`() {
|
||||
@Test fun `should sign a unique transaction with a valid time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.setTime(Instant.now(), 30.seconds)
|
||||
tx.addTimeWindow(Instant.now(), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ class NotaryServiceTests {
|
||||
signatures.forEach { it.verify(stx.id) }
|
||||
}
|
||||
|
||||
@Test fun `should sign a unique transaction without a timestamp`() {
|
||||
@Test fun `should sign a unique transaction without a time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
@ -64,18 +64,18 @@ class NotaryServiceTests {
|
||||
signatures.forEach { it.verify(stx.id) }
|
||||
}
|
||||
|
||||
@Test fun `should report error for transaction with an invalid timestamp`() {
|
||||
@Test fun `should report error for transaction with an invalid time-window`() {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.setTime(Instant.now().plusSeconds(3600), 30.seconds)
|
||||
tx.addTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
val future = runNotaryClient(stx)
|
||||
|
||||
val ex = assertFailsWith(NotaryException::class) { future.getOrThrow() }
|
||||
assertThat(ex.error).isInstanceOf(NotaryError.TimestampInvalid::class.java)
|
||||
assertThat(ex.error).isInstanceOf(NotaryError.TimeWindowInvalid::class.java)
|
||||
}
|
||||
|
||||
@Test fun `should sign identical transaction multiple times (signing is idempotent)`() {
|
||||
|
@ -701,7 +701,7 @@ class VaultQueryTests {
|
||||
val issuance = MEGA_CORP.ref(1)
|
||||
val commercialPaper =
|
||||
CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
|
||||
setTime(TEST_TX_TIME, 30.seconds)
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
Reference in New Issue
Block a user