Rename Timestamp to TimeWindow (#706)

Rename Timestamp to TimeWindow + refactoring
This commit is contained in:
Konstantinos Chalkias
2017-05-25 13:18:49 +01:00
committed by GitHub
parent 1aae41214f
commit 9f2b44f8f7
76 changed files with 382 additions and 387 deletions

View File

@ -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 -> {

View File

@ -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" }

View File

@ -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 {

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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)
}
}

View File

@ -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) {

View File

@ -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)
}
}

View File

@ -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) {

View File

@ -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))

View File

@ -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))))
}

View File

@ -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))))
}

View File

@ -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)`() {

View File

@ -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()