mirror of
https://github.com/corda/corda.git
synced 2024-12-18 20:47:57 +00:00
Changes the name of the addTimeWindow method to setTimeWindow.
This commit is contained in:
parent
7eaac8a306
commit
65f385953f
@ -40,7 +40,7 @@ open class TransactionBuilder(
|
||||
protected val outputs: MutableList<TransactionState<ContractState>> = arrayListOf(),
|
||||
protected val commands: MutableList<Command> = arrayListOf(),
|
||||
protected val signers: MutableSet<PublicKey> = mutableSetOf(),
|
||||
protected var timeWindow: TimeWindow? = null) {
|
||||
window: TimeWindow? = null) {
|
||||
constructor(type: TransactionType, notary: Party) : this(type, notary, (Strand.currentStrand() as? FlowStateMachine<*>)?.id?.uuid ?: UUID.randomUUID())
|
||||
|
||||
/**
|
||||
@ -55,7 +55,7 @@ open class TransactionBuilder(
|
||||
outputs = ArrayList(outputs),
|
||||
commands = ArrayList(commands),
|
||||
signers = LinkedHashSet(signers),
|
||||
timeWindow = timeWindow
|
||||
window = timeWindow
|
||||
)
|
||||
|
||||
// DOCSTART 1
|
||||
@ -120,24 +120,27 @@ open class TransactionBuilder(
|
||||
fun addCommand(data: CommandData, vararg keys: PublicKey) = addCommand(Command(data, listOf(*keys)))
|
||||
fun addCommand(data: CommandData, keys: List<PublicKey>) = addCommand(Command(data, keys))
|
||||
|
||||
var timeWindow: TimeWindow? = window
|
||||
/**
|
||||
* Sets the [TimeWindow] for this transaction, replacing the existing [TimeWindow] if there is one. To be valid, the
|
||||
* transaction must then be signed by the notary service within this window of time. In this way, the notary acts as
|
||||
* the Timestamp Authority.
|
||||
*/
|
||||
set(value) {
|
||||
check(notary != null) { "Only notarised transactions can have a time-window" }
|
||||
signers.add(notary!!.owningKey)
|
||||
field = value
|
||||
}
|
||||
|
||||
/**
|
||||
* Places a [TimeWindow] in this transaction, removing any existing command if there is one.
|
||||
* The command requires a signature from the Notary service, which acts as a Timestamp Authority.
|
||||
* The signature can be obtained using [NotaryFlow].
|
||||
*
|
||||
* The window of time in which the final time-window may lie is defined as [time] +/- [timeTolerance].
|
||||
* If you want a non-symmetrical time window you must add the command via [addCommand] yourself. The tolerance
|
||||
* should be chosen such that your code can finish building the transaction and sending it to the TSA within that
|
||||
* window of time, taking into account factors such as network latency. Transactions being built by a group of
|
||||
* The [TimeWindow] for the transaction can also be defined as [time] +/- [timeTolerance]. The tolerance should be
|
||||
* chosen such that your code can finish building the transaction and sending it to the Timestamp Authority within
|
||||
* that window of time, taking into account factors such as network latency. Transactions being built by a group of
|
||||
* collaborating parties may therefore require a higher time tolerance than a transaction being built by a single
|
||||
* node.
|
||||
*/
|
||||
fun addTimeWindow(time: Instant, timeTolerance: Duration) = addTimeWindow(TimeWindow.withTolerance(time, timeTolerance))
|
||||
|
||||
fun addTimeWindow(timeWindow: TimeWindow) {
|
||||
check(notary != null) { "Only notarised transactions can have a time-window" }
|
||||
signers.add(notary!!.owningKey)
|
||||
this.timeWindow = timeWindow
|
||||
fun setTimeWindow(time: Instant, timeTolerance: Duration) {
|
||||
timeWindow = TimeWindow.withTolerance(time, timeTolerance)
|
||||
}
|
||||
|
||||
// Accessors that yield immutable snapshots.
|
||||
@ -200,4 +203,4 @@ open class TransactionBuilder(
|
||||
require(commands.any { it.signers.any { sig.by in it.keys } }) { "Signature key doesn't match any command" }
|
||||
sig.verify(toWireTransaction().id)
|
||||
}
|
||||
}
|
||||
}
|
@ -99,7 +99,7 @@ class TransactionSerializationTests {
|
||||
|
||||
@Test
|
||||
fun timeWindow() {
|
||||
tx.addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
tx.setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
val ptx = megaCorpServices.signInitialTransaction(tx)
|
||||
val stx = notaryServices.addSignature(ptx)
|
||||
assertEquals(TEST_TX_TIME, stx.tx.timeWindow?.midpoint)
|
||||
|
@ -30,6 +30,7 @@ import net.corda.flows.SignTransactionFlow;
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
|
||||
import java.security.PublicKey;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -303,7 +304,10 @@ public class FlowCookbookJava {
|
||||
regTxBuilder.addOutputState(ourOutput);
|
||||
regTxBuilder.addCommand(ourCommand);
|
||||
regTxBuilder.addAttachment(ourAttachment);
|
||||
regTxBuilder.addTimeWindow(ourTimeWindow);
|
||||
|
||||
// We set the time-window within which the transaction must be notarised using either of:
|
||||
regTxBuilder.setTimeWindow(ourTimeWindow);
|
||||
regTxBuilder.setTimeWindow(getServiceHub().getClock().instant(), Duration.ofSeconds(30));
|
||||
|
||||
/*-----------------------
|
||||
* TRANSACTION SIGNING *
|
||||
|
@ -29,6 +29,7 @@ import net.corda.flows.ResolveTransactionsFlow
|
||||
import net.corda.flows.SignTransactionFlow
|
||||
import org.bouncycastle.asn1.x500.X500Name
|
||||
import java.security.PublicKey
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
|
||||
// We group our two flows inside a singleton object to indicate that they work
|
||||
@ -286,7 +287,10 @@ object FlowCookbook {
|
||||
regTxBuilder.addOutputState(ourOutput)
|
||||
regTxBuilder.addCommand(ourCommand)
|
||||
regTxBuilder.addAttachment(ourAttachment)
|
||||
regTxBuilder.addTimeWindow(ourTimeWindow)
|
||||
|
||||
// We set the time-window within which the transaction must be notarised using either of:
|
||||
regTxBuilder.timeWindow = ourTimeWindow
|
||||
regTxBuilder.setTimeWindow(serviceHub.clock.instant(), Duration.ofSeconds(30))
|
||||
|
||||
/**----------------------
|
||||
* TRANSACTION SIGNING *
|
||||
|
@ -123,7 +123,7 @@ class SubmitTradeApprovalFlow(val tradeId: String,
|
||||
// Create the TransactionBuilder and populate with the new state.
|
||||
val tx = TransactionType.General.Builder(notary)
|
||||
.withItems(tradeProposal, Command(TradeApprovalContract.Commands.Issue(), listOf(tradeProposal.source.owningKey)))
|
||||
tx.addTimeWindow(serviceHub.clock.instant(), Duration.ofSeconds(60))
|
||||
tx.setTimeWindow(serviceHub.clock.instant(), Duration.ofSeconds(60))
|
||||
// We can automatically sign as there is no untrusted data.
|
||||
val signedTx = serviceHub.signInitialTransaction(tx)
|
||||
// Notarise and distribute.
|
||||
@ -184,7 +184,7 @@ class SubmitCompletionFlow(val ref: StateRef, val verdict: WorkflowState) : Flow
|
||||
newState,
|
||||
Command(TradeApprovalContract.Commands.Completed(),
|
||||
listOf(serviceHub.myInfo.legalIdentity.owningKey, latestRecord.state.data.source.owningKey)))
|
||||
tx.addTimeWindow(serviceHub.clock.instant(), Duration.ofSeconds(60))
|
||||
tx.setTimeWindow(serviceHub.clock.instant(), Duration.ofSeconds(60))
|
||||
// We can sign this transaction immediately as we have already checked all the fields and the decision
|
||||
// is ultimately a manual one from the caller.
|
||||
// As a SignedTransaction we can pass the data around certain that it cannot be modified,
|
||||
|
@ -543,7 +543,7 @@ class Obligation<P : Any> : Contract {
|
||||
}
|
||||
tx.addCommand(Commands.SetLifecycle(lifecycle), partiesUsed.map { it.owningKey }.distinct())
|
||||
}
|
||||
tx.addTimeWindow(issuanceDef.dueBefore, issuanceDef.timeTolerance)
|
||||
tx.setTimeWindow(issuanceDef.dueBefore, issuanceDef.timeTolerance)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -183,9 +183,9 @@ object TwoPartyDealFlow {
|
||||
val deal = handshake.payload.dealBeingOffered
|
||||
val ptx = deal.generateAgreement(handshake.payload.notary)
|
||||
|
||||
// And add a request for a time-window: it may be that none of the contracts need this!
|
||||
// We set the transaction's time-window: it may be that none of the contracts need this!
|
||||
// But it can't hurt to have one.
|
||||
ptx.addTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
ptx.setTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
return Pair(ptx, arrayListOf(deal.participants.single { it == serviceHub.myInfo.legalIdentity as AbstractParty }.owningKey))
|
||||
}
|
||||
}
|
||||
|
@ -195,10 +195,10 @@ object TwoPartyTradeFlow {
|
||||
tx.addOutputState(state, tradeRequest.assetForSale.state.notary)
|
||||
tx.addCommand(command, tradeRequest.assetForSale.state.data.owner.owningKey)
|
||||
|
||||
// And add a request for a time-window: it may be that none of the contracts need this!
|
||||
// We set the transaction's time-window: it may be that none of the contracts need this!
|
||||
// But it can't hurt to have one.
|
||||
val currentTime = serviceHub.clock.instant()
|
||||
tx.addTimeWindow(currentTime, 30.seconds)
|
||||
tx.setTimeWindow(currentTime, 30.seconds)
|
||||
return Pair(tx, cashSigningPubKeys)
|
||||
}
|
||||
// DOCEND 1
|
||||
|
@ -260,7 +260,7 @@ class CommercialPaperTestsGeneric {
|
||||
val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER
|
||||
val issuance = bigCorpServices.myInfo.legalIdentity.ref(1)
|
||||
val issueBuilder = CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY)
|
||||
issueBuilder.addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
issueBuilder.setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
val issuePtx = bigCorpServices.signInitialTransaction(issueBuilder)
|
||||
val issueTx = notaryServices.addSignature(issuePtx)
|
||||
|
||||
@ -289,7 +289,7 @@ class CommercialPaperTestsGeneric {
|
||||
databaseBigCorp.transaction {
|
||||
fun makeRedeemTX(time: Instant): Pair<SignedTransaction, UUID> {
|
||||
val builder = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
builder.addTimeWindow(time, 30.seconds)
|
||||
builder.setTimeWindow(time, 30.seconds)
|
||||
CommercialPaper().generateRedeem(builder, moveTX.tx.outRef(1), bigCorpVaultService)
|
||||
val ptx = aliceServices.signInitialTransaction(builder)
|
||||
val ptx2 = bigCorpServices.addSignature(ptx)
|
||||
|
@ -172,7 +172,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.addTimeWindow(Instant.now(), 30.seconds)
|
||||
tx.setTimeWindow(Instant.now(), 30.seconds)
|
||||
val stx = node.services.signInitialTransaction(tx)
|
||||
node.services.recordTransactions(stx)
|
||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||
|
@ -43,7 +43,7 @@ class NotaryServiceTests {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.addTimeWindow(Instant.now(), 30.seconds)
|
||||
tx.setTimeWindow(Instant.now(), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
@ -68,7 +68,7 @@ class NotaryServiceTests {
|
||||
val stx = run {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionType.General.Builder(notaryNode.info.notaryIdentity).withItems(inputState)
|
||||
tx.addTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
|
||||
tx.setTimeWindow(Instant.now().plusSeconds(3600), 30.seconds)
|
||||
clientNode.services.signInitialTransaction(tx)
|
||||
}
|
||||
|
||||
|
@ -1241,7 +1241,7 @@ class VaultQueryTests {
|
||||
val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER
|
||||
val commercialPaper =
|
||||
CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -1251,7 +1251,7 @@ class VaultQueryTests {
|
||||
val faceValue2 = 10000.POUNDS `issued by` DUMMY_CASH_ISSUER
|
||||
val commercialPaper2 =
|
||||
CommercialPaper().generateIssue(issuance, faceValue2, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -1278,7 +1278,7 @@ class VaultQueryTests {
|
||||
val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER
|
||||
val commercialPaper =
|
||||
CommercialPaper().generateIssue(issuance, faceValue, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
@ -1288,7 +1288,7 @@ class VaultQueryTests {
|
||||
val faceValue2 = 5000.POUNDS `issued by` DUMMY_CASH_ISSUER
|
||||
val commercialPaper2 =
|
||||
CommercialPaper().generateIssue(issuance, faceValue2, TEST_TX_TIME + 30.days, DUMMY_NOTARY).apply {
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
@ -72,9 +72,9 @@ object FixingFlow {
|
||||
override fun beforeSigning(fix: Fix) {
|
||||
newDeal.generateFix(ptx, StateAndRef(txState, handshake.payload.ref), fix)
|
||||
|
||||
// And add a request for a time-window: it may be that none of the contracts need this!
|
||||
// We set the transaction's time-window: it may be that none of the contracts need this!
|
||||
// But it can't hurt to have one.
|
||||
ptx.addTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
ptx.setTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
}
|
||||
|
||||
@Suspendable
|
||||
|
@ -227,7 +227,7 @@ class IRSTests {
|
||||
calculation = dummyIRS.calculation,
|
||||
common = dummyIRS.common,
|
||||
notary = DUMMY_NOTARY).apply {
|
||||
addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
}
|
||||
val ptx1 = megaCorpServices.signInitialTransaction(gtx)
|
||||
val ptx2 = miniCorpServices.addSignature(ptx1)
|
||||
@ -311,7 +311,7 @@ class IRSTests {
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val fixing = Fix(nextFix, "0.052".percent.value)
|
||||
InterestRateSwap().generateFix(tx, previousTXN.tx.outRef(0), fixing)
|
||||
tx.addTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
tx.setTimeWindow(TEST_TX_TIME, 30.seconds)
|
||||
val ptx1 = megaCorpServices.signInitialTransaction(tx)
|
||||
val ptx2 = miniCorpServices.addSignature(ptx1)
|
||||
notaryServices.addSignature(ptx2)
|
||||
|
@ -20,7 +20,7 @@ object StateRevisionFlow {
|
||||
override fun assembleTx(): AbstractStateReplacementFlow.UpgradeTx {
|
||||
val state = originalState.state.data
|
||||
val tx = state.generateRevision(originalState.state.notary, originalState, modification)
|
||||
tx.addTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
tx.setTimeWindow(serviceHub.clock.instant(), 30.seconds)
|
||||
|
||||
val stx = serviceHub.signInitialTransaction(tx)
|
||||
val participantKeys = state.participants.map { it.owningKey }
|
||||
|
@ -82,7 +82,7 @@ class SellerFlow(val otherParty: Party,
|
||||
tx.addAttachment(serviceHub.attachments.openAttachment(PROSPECTUS_HASH)!!.id)
|
||||
|
||||
// Requesting a time-window to be set, all CP must have a validation window.
|
||||
tx.addTimeWindow(Instant.now(), 30.seconds)
|
||||
tx.setTimeWindow(Instant.now(), 30.seconds)
|
||||
|
||||
// Sign it as ourselves.
|
||||
val stx = serviceHub.signInitialTransaction(tx)
|
||||
|
@ -145,7 +145,7 @@ data class TestTransactionDSLInterpreter private constructor(
|
||||
}
|
||||
|
||||
override fun timeWindow(data: TimeWindow) {
|
||||
transactionBuilder.addTimeWindow(data)
|
||||
transactionBuilder.timeWindow = data
|
||||
}
|
||||
|
||||
override fun tweak(
|
||||
|
@ -52,7 +52,7 @@ interface TransactionDSLInterpreter : Verifies, OutputStateLookup {
|
||||
fun _command(signers: List<PublicKey>, commandData: CommandData)
|
||||
|
||||
/**
|
||||
* Adds a time-window to the transaction.
|
||||
* Sets the time-window of the transaction.
|
||||
* @param data the [TimeWindow] (validation window).
|
||||
*/
|
||||
fun timeWindow(data: TimeWindow)
|
||||
@ -116,7 +116,7 @@ class TransactionDSL<out T : TransactionDSLInterpreter>(val interpreter: T) : Tr
|
||||
fun command(signer: PublicKey, commandData: CommandData) = _command(listOf(signer), commandData)
|
||||
|
||||
/**
|
||||
* Adds a [TimeWindow] command to the transaction.
|
||||
* Sets the [TimeWindow] of the transaction.
|
||||
* @param time The [Instant] of the [TimeWindow].
|
||||
* @param tolerance The tolerance of the [TimeWindow].
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user