mirror of
https://github.com/corda/corda.git
synced 2025-01-26 06:09:25 +00:00
Made TransactionBuilder abstract. Every transaction type now needs to implement and provide its own Builder. This is required since for specific types we need to run different logic when adding new items to the transaction. For example, when adding a new input state to a transaction of type NotaryChange we need to add all of the states participants to the signers list.
This commit is contained in:
parent
9958b5c603
commit
0a5b7ace35
@ -36,8 +36,8 @@ class AnotherDummyContract : Contract, com.r3corda.core.node.DummyContractBackdo
|
||||
override val legalContractReference: SecureHash = SecureHash.sha256("https://anotherdummy.org")
|
||||
|
||||
override fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
|
||||
val state = TransactionState(State(magicNumber), notary)
|
||||
return TransactionBuilder().withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
val state = State(magicNumber)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
|
||||
override fun inspectState(state: ContractState): Int = (state as State).magicNumber
|
||||
|
@ -232,7 +232,7 @@ public class JavaCommercialPaper implements Contract {
|
||||
public TransactionBuilder generateIssue(@NotNull PartyAndReference issuance, @NotNull Amount faceValue, @Nullable Instant maturityDate, @NotNull Party notary) {
|
||||
State state = new State(issuance, issuance.getParty().getOwningKey(), faceValue, maturityDate);
|
||||
TransactionState output = new TransactionState<>(state, notary);
|
||||
return new TransactionBuilder().withItems(output, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
|
||||
return new TransactionType.General.Builder().withItems(output, new Command(new Commands.Issue(), issuance.getParty().getOwningKey()));
|
||||
}
|
||||
|
||||
public void generateRedeem(TransactionBuilder tx, StateAndRef<State> paper, List<StateAndRef<Cash.State>> wallet) throws InsufficientBalanceException {
|
||||
|
@ -139,7 +139,7 @@ class CommercialPaper : Contract {
|
||||
fun generateIssue(faceValue: Amount<Issued<Currency>>, maturityDate: Instant, notary: Party): TransactionBuilder {
|
||||
val issuance = faceValue.token.issuer
|
||||
val state = TransactionState(State(issuance, issuance.party.owningKey, faceValue, maturityDate), notary)
|
||||
return TransactionBuilder().withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Issue(), issuance.party.owningKey))
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -717,8 +717,8 @@ class InterestRateSwap() : Contract {
|
||||
val newCalculation = Calculation(calculation.expression, floatingLegPaymentSchedule, fixedLegPaymentSchedule)
|
||||
|
||||
// Put all the above into a new State object.
|
||||
val state = TransactionState(State(fixedLeg, floatingLeg, newCalculation, common), notary)
|
||||
return TransactionBuilder().withItems(state, Command(Commands.Agree(), listOf(state.data.floatingLeg.floatingRatePayer.owningKey, state.data.fixedLeg.fixedRatePayer.owningKey)))
|
||||
val state = State(fixedLeg, floatingLeg, newCalculation, common)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Agree(), listOf(state.floatingLeg.floatingRatePayer.owningKey, state.fixedLeg.fixedRatePayer.owningKey)))
|
||||
}
|
||||
|
||||
private fun calcFixingDate(date: LocalDate, fixingPeriod: DateOffset, calendar: BusinessCalendar): LocalDate {
|
||||
@ -733,9 +733,9 @@ class InterestRateSwap() : Contract {
|
||||
fun generateFix(tx: TransactionBuilder, irs: StateAndRef<State>, fixing: Pair<LocalDate, Rate>) {
|
||||
tx.addInputState(irs)
|
||||
tx.addOutputState(
|
||||
TransactionState(
|
||||
irs.state.data.copy(calculation = irs.state.data.calculation.applyFixing(fixing.first, FixedRate(fixing.second))),
|
||||
irs.state.notary))
|
||||
irs.state.data.copy(calculation = irs.state.data.calculation.applyFixing(fixing.first, FixedRate(fixing.second))),
|
||||
irs.state.notary
|
||||
)
|
||||
tx.addCommand(Commands.Fix(), listOf(irs.state.data.floatingLeg.floatingRatePayer.owningKey, irs.state.data.fixedLeg.fixedRatePayer.owningKey))
|
||||
}
|
||||
}
|
||||
|
@ -266,7 +266,7 @@ object TwoPartyTradeProtocol {
|
||||
}
|
||||
|
||||
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> {
|
||||
val ptx = TransactionBuilder()
|
||||
val ptx = TransactionType.General.Builder()
|
||||
// Add input and output states for the movement of cash, by using the Cash contract to generate the states.
|
||||
val wallet = serviceHub.walletService.currentWallet
|
||||
val cashStates = wallet.statesOfType<Cash.State>()
|
||||
@ -279,7 +279,7 @@ object TwoPartyTradeProtocol {
|
||||
// initial seed in order to provide privacy protection.
|
||||
val freshKey = serviceHub.keyManagementService.freshKey()
|
||||
val (command, state) = tradeRequest.assetForSale.state.data.withNewOwner(freshKey.public)
|
||||
ptx.addOutputState(TransactionState(state, tradeRequest.assetForSale.state.notary))
|
||||
ptx.addOutputState(state, tradeRequest.assetForSale.state.notary)
|
||||
ptx.addCommand(command, tradeRequest.assetForSale.state.data.owner)
|
||||
|
||||
// And add a request for timestamping: it may be that none of the contracts need this! But it can't hurt
|
||||
|
@ -140,7 +140,7 @@ class CommercialPaperTestsGeneric {
|
||||
}
|
||||
|
||||
fun <T : ContractState> cashOutputsToWallet(vararg outputs: TransactionState<T>): Pair<LedgerTransaction, List<StateAndRef<T>>> {
|
||||
val ltx = LedgerTransaction(emptyList(), emptyList(), listOf(*outputs), emptyList(), SecureHash.randomSHA256(), emptyList(), TransactionType.Business())
|
||||
val ltx = LedgerTransaction(emptyList(), emptyList(), listOf(*outputs), emptyList(), SecureHash.randomSHA256(), emptyList(), TransactionType.General())
|
||||
return Pair(ltx, outputs.mapIndexed { index, state -> StateAndRef(state, StateRef(ltx.id, index)) })
|
||||
}
|
||||
|
||||
@ -165,7 +165,7 @@ class CommercialPaperTestsGeneric {
|
||||
|
||||
// Alice pays $9000 to MiniCorp to own some of their debt.
|
||||
val moveTX: LedgerTransaction = run {
|
||||
val ptx = TransactionBuilder()
|
||||
val ptx = TransactionType.General.Builder()
|
||||
Cash().generateSpend(ptx, 9000.DOLLARS, MINI_CORP_PUBKEY, alicesWallet)
|
||||
CommercialPaper().generateMove(ptx, issueTX.outRef(0), ALICE_PUBKEY)
|
||||
ptx.signWith(MINI_CORP_KEY)
|
||||
@ -181,7 +181,7 @@ class CommercialPaperTestsGeneric {
|
||||
)
|
||||
|
||||
fun makeRedeemTX(time: Instant): LedgerTransaction {
|
||||
val ptx = TransactionBuilder()
|
||||
val ptx = TransactionType.General.Builder()
|
||||
ptx.setTime(time, DUMMY_NOTARY, 30.seconds)
|
||||
CommercialPaper().generateRedeem(ptx, moveTX.outRef(1), corpWallet)
|
||||
ptx.signWith(ALICE_KEY)
|
||||
|
@ -311,7 +311,7 @@ class IRSTests {
|
||||
val nextFixingDate = currentIRS.calculation.nextFixingDate() ?: break
|
||||
println("\n\n\n ***** Applying a fixing to $nextFixingDate \n\n\n")
|
||||
var fixTX: LedgerTransaction = run {
|
||||
val tx = TransactionBuilder()
|
||||
val tx = TransactionType.General.Builder()
|
||||
val fixing = Pair(nextFixingDate, FixedRate("0.052".percent))
|
||||
InterestRateSwap().generateFix(tx, previousTXN.outRef(0), fixing)
|
||||
with(tx) {
|
||||
|
@ -97,7 +97,7 @@ class CashTests {
|
||||
}
|
||||
|
||||
// Test generation works.
|
||||
val ptx = TransactionBuilder()
|
||||
val ptx = TransactionType.General.Builder()
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
||||
assertTrue(ptx.inputStates().isEmpty())
|
||||
val s = ptx.outputStates()[0].data as Cash.State
|
||||
@ -109,7 +109,7 @@ class CashTests {
|
||||
|
||||
// Test issuance from the issuance definition
|
||||
val amount = 100.DOLLARS `issued by` MINI_CORP.ref(12, 34)
|
||||
val templatePtx = TransactionBuilder()
|
||||
val templatePtx = TransactionType.General.Builder()
|
||||
Cash().generateIssue(templatePtx, amount, owner = DUMMY_PUBKEY_1, notary = DUMMY_NOTARY)
|
||||
assertTrue(templatePtx.inputStates().isEmpty())
|
||||
assertEquals(ptx.outputStates()[0], templatePtx.outputStates()[0])
|
||||
@ -176,14 +176,14 @@ class CashTests {
|
||||
@Test(expected = IllegalStateException::class)
|
||||
fun `reject issuance with inputs`() {
|
||||
// Issue some cash
|
||||
var ptx = TransactionBuilder()
|
||||
var ptx = TransactionType.General.Builder()
|
||||
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY)
|
||||
ptx.signWith(MINI_CORP_KEY)
|
||||
val tx = ptx.toSignedTransaction()
|
||||
|
||||
// Include the previously issued cash in a new issuance command
|
||||
ptx = TransactionBuilder()
|
||||
ptx = TransactionType.General.Builder()
|
||||
ptx.addInputState(tx.tx.outRef<Cash.State>(0))
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY)
|
||||
}
|
||||
@ -386,7 +386,7 @@ class CashTests {
|
||||
)
|
||||
|
||||
fun makeSpend(amount: Amount<Currency>, dest: PublicKey, corp: Party, depositRef: OpaqueBytes = defaultRef): WireTransaction {
|
||||
val tx = TransactionBuilder()
|
||||
val tx = TransactionType.General.Builder()
|
||||
Cash().generateSpend(tx, amount, dest, WALLET)
|
||||
return tx.toWireTransaction()
|
||||
}
|
||||
@ -401,7 +401,7 @@ class CashTests {
|
||||
|
||||
@Test
|
||||
fun generateSimpleSpendWithParties() {
|
||||
val tx = TransactionBuilder()
|
||||
val tx = TransactionType.General.Builder()
|
||||
Cash().generateSpend(tx, 80.DOLLARS, ALICE_PUBKEY, WALLET, setOf(MINI_CORP))
|
||||
assertEquals(WALLET[2].ref, tx.inputStates()[0])
|
||||
}
|
||||
|
@ -43,7 +43,7 @@ class DummyContract : Contract {
|
||||
override val legalContractReference: SecureHash = SecureHash.sha256("")
|
||||
|
||||
fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
|
||||
val state = TransactionState(SingleOwnerState(magicNumber, owner.party.owningKey), notary)
|
||||
return TransactionBuilder().withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
val state = SingleOwnerState(magicNumber, owner.party.owningKey)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
}
|
@ -14,12 +14,13 @@ import java.util.*
|
||||
* Then once the states and commands are right, this class can be used as a holding bucket to gather signatures from
|
||||
* multiple parties.
|
||||
*/
|
||||
open class TransactionBuilder(protected val inputs: MutableList<StateRef> = arrayListOf(),
|
||||
protected val attachments: MutableList<SecureHash> = arrayListOf(),
|
||||
protected val outputs: MutableList<TransactionState<ContractState>> = arrayListOf(),
|
||||
protected val commands: MutableList<Command> = arrayListOf(),
|
||||
protected val signers: MutableSet<PublicKey> = mutableSetOf(),
|
||||
protected val type: TransactionType = TransactionType.Business()) {
|
||||
abstract class TransactionBuilder(protected val type: TransactionType = TransactionType.General(),
|
||||
protected val notary: Party? = null) {
|
||||
protected val inputs: MutableList<StateRef> = arrayListOf()
|
||||
protected val attachments: MutableList<SecureHash> = arrayListOf()
|
||||
protected val outputs: MutableList<TransactionState<ContractState>> = arrayListOf()
|
||||
protected val commands: MutableList<Command> = arrayListOf()
|
||||
protected val signers: MutableSet<PublicKey> = mutableSetOf()
|
||||
|
||||
val time: TimestampCommand? get() = commands.mapNotNull { it.value as? TimestampCommand }.singleOrNull()
|
||||
|
||||
@ -47,6 +48,7 @@ open class TransactionBuilder(protected val inputs: MutableList<StateRef> = arra
|
||||
when (t) {
|
||||
is StateAndRef<*> -> addInputState(t)
|
||||
is TransactionState<*> -> addOutputState(t)
|
||||
is ContractState -> addOutputState(t)
|
||||
is Command -> addCommand(t)
|
||||
else -> throw IllegalArgumentException("Wrong argument type: ${t.javaClass}")
|
||||
}
|
||||
@ -123,6 +125,13 @@ open class TransactionBuilder(protected val inputs: MutableList<StateRef> = arra
|
||||
outputs.add(state)
|
||||
}
|
||||
|
||||
fun addOutputState(state: ContractState, notary: Party) = addOutputState(TransactionState(state, notary))
|
||||
|
||||
fun addOutputState(state: ContractState) {
|
||||
checkNotNull(notary) { "Need to specify a Notary for the state, or set a default one on TransactionBuilder initialisation" }
|
||||
addOutputState(state, notary!!)
|
||||
}
|
||||
|
||||
fun addCommand(arg: Command) {
|
||||
check(currentSigs.isEmpty())
|
||||
// TODO: replace pubkeys in commands with 'pointers' to keys in signers
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.r3corda.core.contracts
|
||||
|
||||
import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.noneOrSingle
|
||||
import java.security.PublicKey
|
||||
|
||||
@ -45,8 +46,10 @@ sealed class TransactionType {
|
||||
/** Implement type specific transaction validation logic */
|
||||
abstract fun verifyTransaction(tx: TransactionForVerification)
|
||||
|
||||
/** A general type used for business transactions, where transaction validity is determined by custom contract code */
|
||||
class Business : TransactionType() {
|
||||
/** A general transaction type where transaction validity is determined by custom contract code */
|
||||
class General : TransactionType() {
|
||||
class Builder(notary: Party? = null) : TransactionBuilder(General(), notary) {}
|
||||
|
||||
/**
|
||||
* Check the transaction is contract-valid by running the verify() for each input and output state contract.
|
||||
* If any contract fails to verify, the whole transaction is considered to be invalid
|
||||
@ -80,7 +83,7 @@ sealed class TransactionType {
|
||||
* A transaction builder that automatically sets the transaction type to [NotaryChange]
|
||||
* and adds the list of participants to the signers set for every input state.
|
||||
*/
|
||||
class Builder() : TransactionBuilder(type = NotaryChange()) {
|
||||
class Builder(notary: Party? = null) : TransactionBuilder(NotaryChange(), notary) {
|
||||
override fun addInputState(stateAndRef: StateAndRef<*>) {
|
||||
signers.addAll(stateAndRef.state.data.participants)
|
||||
super.addInputState(stateAndRef)
|
||||
|
@ -109,7 +109,7 @@ abstract class AbstractTransactionForTest {
|
||||
protected val outStates = ArrayList<LabeledOutput>()
|
||||
protected val commands = ArrayList<Command>()
|
||||
protected val signers = LinkedHashSet<PublicKey>()
|
||||
protected val type = TransactionType.Business()
|
||||
protected val type = TransactionType.General()
|
||||
|
||||
open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, TransactionState(s(), DUMMY_NOTARY)).apply { outStates.add(this) }
|
||||
|
||||
@ -298,7 +298,7 @@ class TransactionGroupDSL<T : ContractState>(private val stateType: Class<T>) {
|
||||
inner class Roots {
|
||||
fun transaction(vararg outputStates: LabeledOutput) {
|
||||
val outs = outputStates.map { it.state }
|
||||
val wtx = WireTransaction(emptyList(), emptyList(), outs, emptyList(), emptyList(), TransactionType.Business())
|
||||
val wtx = WireTransaction(emptyList(), emptyList(), outs, emptyList(), emptyList(), TransactionType.General())
|
||||
for ((index, state) in outputStates.withIndex()) {
|
||||
val label = state.label!!
|
||||
labelToRefs[label] = StateRef(wtx.id, index)
|
||||
|
@ -367,9 +367,8 @@ object TwoPartyDealProtocol {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
val newDeal = deal
|
||||
val oldRef = dealToFix.ref
|
||||
|
||||
val ptx = TransactionBuilder()
|
||||
val ptx = TransactionType.General.Builder()
|
||||
val addFixing = object : RatesFixProtocol(ptx, serviceHub.networkMapCache.ratesOracleNodes[0], fixOf, BigDecimal.ZERO, BigDecimal.ONE) {
|
||||
@Suspendable
|
||||
override fun beforeSigning(fix: Fix) {
|
||||
|
@ -7,7 +7,7 @@ import com.r3corda.core.testing.*
|
||||
import org.junit.Test
|
||||
import java.security.PublicKey
|
||||
import java.security.SecureRandom
|
||||
import java.util.Currency
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
import kotlin.test.assertNotEquals
|
||||
@ -122,7 +122,7 @@ class TransactionGroupTests {
|
||||
// We have to do this manually without the DSL because transactionGroup { } won't let us create a tx that
|
||||
// points nowhere.
|
||||
val input = StateAndRef(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY, generateStateRef())
|
||||
tg.txns += TransactionBuilder().apply {
|
||||
tg.txns += TransactionType.General.Builder().apply {
|
||||
addInputState(input)
|
||||
addOutputState(A_THOUSAND_POUNDS `with notary` DUMMY_NOTARY)
|
||||
addCommand(TestCash.Commands.Move(), BOB_PUBKEY)
|
||||
|
@ -51,8 +51,8 @@ class AttachmentClassLoaderTests {
|
||||
override val legalContractReference: SecureHash = SecureHash.sha256("")
|
||||
|
||||
fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
|
||||
val state = TransactionState(State(magicNumber), notary)
|
||||
return TransactionBuilder().withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
val state = State(magicNumber)
|
||||
return TransactionType.General.Builder(notary = notary).withItems(state, Command(Commands.Create(), owner.party.owningKey))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,7 @@ import org.junit.Test
|
||||
import java.security.PublicKey
|
||||
import java.security.SecureRandom
|
||||
import java.security.SignatureException
|
||||
import java.util.Currency
|
||||
import java.util.*
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertFailsWith
|
||||
|
||||
@ -53,7 +53,7 @@ class TransactionSerializationTests {
|
||||
|
||||
@Before
|
||||
fun setup() {
|
||||
tx = TransactionBuilder().withItems(
|
||||
tx = TransactionType.General.Builder().withItems(
|
||||
inputState, outputState, changeState, Command(TestCash.Commands.Move(), arrayListOf(TestUtils.keypair.public))
|
||||
)
|
||||
}
|
||||
@ -92,7 +92,7 @@ class TransactionSerializationTests {
|
||||
|
||||
// If the signature was replaced in transit, we don't like it.
|
||||
assertFailsWith(SignatureException::class) {
|
||||
val tx2 = TransactionBuilder().withItems(inputState, outputState, changeState,
|
||||
val tx2 = TransactionType.General.Builder().withItems(inputState, outputState, changeState,
|
||||
Command(TestCash.Commands.Move(), TestUtils.keypair2.public))
|
||||
tx2.signWith(DUMMY_NOTARY_KEY)
|
||||
tx2.signWith(TestUtils.keypair2)
|
||||
|
@ -8,9 +8,9 @@ import com.r3corda.contracts.testing.`with notary`
|
||||
import com.r3corda.core.bd
|
||||
import com.r3corda.core.contracts.DOLLARS
|
||||
import com.r3corda.core.contracts.Fix
|
||||
import com.r3corda.core.contracts.TransactionBuilder
|
||||
import com.r3corda.core.crypto.Party
|
||||
import com.r3corda.core.crypto.generateKeyPair
|
||||
import com.r3corda.core.contracts.TransactionType
|
||||
import com.r3corda.core.testing.ALICE_PUBKEY
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
||||
import com.r3corda.core.testing.MEGA_CORP
|
||||
@ -104,7 +104,7 @@ class NodeInterestRatesTest {
|
||||
val (n1, n2) = net.createTwoNodes()
|
||||
n2.interestRatesService.oracle.knownFixes = TEST_DATA
|
||||
|
||||
val tx = TransactionBuilder()
|
||||
val tx = TransactionType.General.Builder()
|
||||
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
|
||||
val protocol = RatesFixProtocol(tx, n2.info, fixOf, "0.675".bd, "0.1".bd)
|
||||
BriefLogFormatter.initVerbose("rates")
|
||||
@ -119,5 +119,5 @@ class NodeInterestRatesTest {
|
||||
assertEquals("0.678".bd, fix.value)
|
||||
}
|
||||
|
||||
private fun makeTX() = TransactionBuilder(outputs = mutableListOf(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY))
|
||||
private fun makeTX() = TransactionType.General.Builder().withItems(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY)
|
||||
}
|
@ -3,7 +3,7 @@ package com.r3corda.node.services
|
||||
import com.r3corda.contracts.cash.Cash
|
||||
import com.r3corda.core.contracts.`issued by`
|
||||
import com.r3corda.core.contracts.DOLLARS
|
||||
import com.r3corda.core.contracts.TransactionBuilder
|
||||
import com.r3corda.core.contracts.TransactionType
|
||||
import com.r3corda.core.contracts.USD
|
||||
import com.r3corda.core.contracts.verifyToLedgerTransaction
|
||||
import com.r3corda.core.node.ServiceHub
|
||||
@ -67,21 +67,21 @@ class NodeWalletServiceTest {
|
||||
|
||||
// A tx that sends us money.
|
||||
val freshKey = services.keyManagementService.freshKey()
|
||||
val usefulTX = TransactionBuilder().apply {
|
||||
val usefulTX = TransactionType.General.Builder().apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
}.toSignedTransaction()
|
||||
val myOutput = usefulTX.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments).outRef<Cash.State>(0)
|
||||
|
||||
// A tx that spends our money.
|
||||
val spendTX = TransactionBuilder().apply {
|
||||
val spendTX = TransactionType.General.Builder().apply {
|
||||
Cash().generateSpend(this, 80.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_PUBKEY, listOf(myOutput))
|
||||
signWith(freshKey)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
}.toSignedTransaction()
|
||||
|
||||
// A tx that doesn't send us anything.
|
||||
val irrelevantTX = TransactionBuilder().apply {
|
||||
val irrelevantTX = TransactionType.General.Builder().apply {
|
||||
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public, DUMMY_NOTARY)
|
||||
signWith(MEGA_CORP_KEY)
|
||||
signWith(DUMMY_NOTARY_KEY)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package com.r3corda.node.services
|
||||
|
||||
import com.r3corda.core.contracts.TimestampCommand
|
||||
import com.r3corda.core.contracts.TransactionBuilder
|
||||
import com.r3corda.core.contracts.TransactionType
|
||||
import com.r3corda.core.seconds
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
||||
@ -38,7 +38,7 @@ class NotaryServiceTests {
|
||||
|
||||
@Test fun `should sign a unique transaction with a valid timestamp`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionBuilder().withItems(inputState)
|
||||
val tx = TransactionType.General.Builder().withItems(inputState)
|
||||
tx.setTime(Instant.now(), DUMMY_NOTARY, 30.seconds)
|
||||
val wtx = tx.toWireTransaction()
|
||||
|
||||
@ -52,7 +52,7 @@ class NotaryServiceTests {
|
||||
|
||||
@Test fun `should sign a unique transaction without a timestamp`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val wtx = TransactionBuilder().withItems(inputState).toWireTransaction()
|
||||
val wtx = TransactionType.General.Builder().withItems(inputState).toWireTransaction()
|
||||
|
||||
val protocol = NotaryProtocol.Client(wtx)
|
||||
val future = clientNode.smm.add(NotaryProtocol.TOPIC, protocol)
|
||||
@ -64,7 +64,7 @@ class NotaryServiceTests {
|
||||
|
||||
@Test fun `should report error for transaction with an invalid timestamp`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionBuilder().withItems(inputState)
|
||||
val tx = TransactionType.General.Builder().withItems(inputState)
|
||||
tx.setTime(Instant.now().plusSeconds(3600), DUMMY_NOTARY, 30.seconds)
|
||||
val wtx = tx.toWireTransaction()
|
||||
|
||||
@ -79,7 +79,7 @@ class NotaryServiceTests {
|
||||
|
||||
@Test fun `should report error for transaction with more than one timestamp`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val tx = TransactionBuilder().withItems(inputState)
|
||||
val tx = TransactionType.General.Builder().withItems(inputState)
|
||||
val timestamp = TimestampCommand(Instant.now(), 30.seconds)
|
||||
tx.addCommand(timestamp, DUMMY_NOTARY.owningKey)
|
||||
tx.addCommand(timestamp, DUMMY_NOTARY.owningKey)
|
||||
@ -96,7 +96,7 @@ class NotaryServiceTests {
|
||||
|
||||
@Test fun `should report conflict for a duplicate transaction`() {
|
||||
val inputState = issueState(clientNode)
|
||||
val wtx = TransactionBuilder().withItems(inputState).toWireTransaction()
|
||||
val wtx = TransactionType.General.Builder().withItems(inputState).toWireTransaction()
|
||||
|
||||
val firstSpend = NotaryProtocol.Client(wtx)
|
||||
val secondSpend = NotaryProtocol.Client(wtx)
|
||||
|
@ -1,6 +1,6 @@
|
||||
package com.r3corda.node.services
|
||||
|
||||
import com.r3corda.core.contracts.TransactionBuilder
|
||||
import com.r3corda.core.contracts.TransactionType
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
||||
import com.r3corda.node.internal.testing.MockNetwork
|
||||
@ -34,7 +34,7 @@ class ValidatingNotaryServiceTests {
|
||||
|
||||
@Test fun `should report error for invalid transaction dependency`() {
|
||||
val inputState = issueInvalidState(clientNode)
|
||||
val wtx = TransactionBuilder().withItems(inputState).toWireTransaction()
|
||||
val wtx = TransactionType.General.Builder().withItems(inputState).toWireTransaction()
|
||||
|
||||
val protocol = NotaryProtocol.Client(wtx)
|
||||
val future = clientNode.smm.add(NotaryProtocol.TOPIC, protocol)
|
||||
|
@ -1,7 +1,10 @@
|
||||
package node.services
|
||||
|
||||
import com.r3corda.contracts.DummyContract
|
||||
import com.r3corda.core.contracts.*
|
||||
import com.r3corda.core.contracts.StateAndRef
|
||||
import com.r3corda.core.contracts.StateRef
|
||||
import com.r3corda.core.contracts.TransactionState
|
||||
import com.r3corda.core.contracts.TransactionType
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
||||
import com.r3corda.node.internal.testing.MockNetwork
|
||||
@ -52,7 +55,7 @@ class NotaryChangeTests {
|
||||
val state = TransactionState(DummyContract.MultiOwnerState(0,
|
||||
listOf(clientNodeA.info.identity.owningKey, clientNodeB.info.identity.owningKey)), DUMMY_NOTARY)
|
||||
|
||||
val tx = TransactionBuilder(type = TransactionType.NotaryChange()).withItems(state)
|
||||
val tx = TransactionType.NotaryChange.Builder().withItems(state)
|
||||
tx.signWith(clientNodeA.storage.myLegalIdentityKey)
|
||||
tx.signWith(clientNodeB.storage.myLegalIdentityKey)
|
||||
tx.signWith(DUMMY_NOTARY_KEY)
|
||||
|
@ -83,7 +83,7 @@ fun main(args: Array<String>) {
|
||||
val notary = node.services.networkMapCache.notaryNodes[0]
|
||||
|
||||
// Make a garbage transaction that includes a rate fix.
|
||||
val tx = TransactionBuilder()
|
||||
val tx = TransactionType.General.Builder()
|
||||
tx.addOutputState(TransactionState(Cash.State(1500.DOLLARS `issued by` node.storage.myLegalIdentity.ref(1), node.keyManagement.freshKey().public), notary.identity))
|
||||
val protocol = RatesFixProtocol(tx, oracleNode, fixOf, expectedRate, rateTolerance)
|
||||
node.smm.add("demo.ratefix", protocol).get()
|
||||
|
@ -369,7 +369,7 @@ class TraderDemoProtocolSeller(val myAddress: HostAndPort,
|
||||
|
||||
// Now make a dummy transaction that moves it to a new key, just to show that resolving dependencies works.
|
||||
val move: SignedTransaction = run {
|
||||
val builder = TransactionBuilder()
|
||||
val builder = TransactionType.General.Builder()
|
||||
CommercialPaper().generateMove(builder, issuance.tx.outRef(0), ownedBy)
|
||||
builder.signWith(keyPair)
|
||||
builder.addSignatureUnchecked(subProtocol(NotaryProtocol.Client(builder.toWireTransaction())))
|
||||
|
Loading…
x
Reference in New Issue
Block a user