mirror of
https://github.com/corda/corda.git
synced 2024-12-22 22:32:26 +00:00
Testing cleanup:
- Move code out of ambiguously named TestUtils files (there were three). Sometimes it's simpler to just put these things into the contract source files directly. - Remove JavaTestHelpers objects (there were three), in favour of just giving the top level kotlin file class better names. - Misc other small tweaks and cleanups.
This commit is contained in:
parent
2cd5014941
commit
cc22810b09
@ -17,7 +17,7 @@ import java.time.Instant;
|
|||||||
import java.util.Currency;
|
import java.util.Currency;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.r3corda.core.contracts.ContractsDSLKt.requireSingleCommand;
|
import static com.r3corda.core.contracts.ContractsDSL.requireSingleCommand;
|
||||||
import static kotlin.collections.CollectionsKt.single;
|
import static kotlin.collections.CollectionsKt.single;
|
||||||
|
|
||||||
|
|
||||||
|
@ -170,3 +170,8 @@ class CommercialPaper : Contract {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = copy(owner = owner)
|
||||||
|
infix fun CommercialPaper.State.`with notary`(notary: Party) = TransactionState(this, notary)
|
||||||
|
infix fun ICommercialPaperState.`owned by`(newOwner: PublicKey) = withOwner(newOwner)
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,10 +1,7 @@
|
|||||||
package com.r3corda.contracts.asset
|
package com.r3corda.contracts.asset
|
||||||
|
|
||||||
import com.r3corda.core.contracts.*
|
import com.r3corda.core.contracts.*
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.*
|
||||||
import com.r3corda.core.crypto.SecureHash
|
|
||||||
import com.r3corda.core.crypto.newSecureRandom
|
|
||||||
import com.r3corda.core.crypto.toStringShort
|
|
||||||
import com.r3corda.core.node.services.Wallet
|
import com.r3corda.core.node.services.Wallet
|
||||||
import com.r3corda.core.utilities.Emoji
|
import com.r3corda.core.utilities.Emoji
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
@ -17,7 +14,6 @@ import java.util.*
|
|||||||
|
|
||||||
// Just a fake program identifier for now. In a real system it could be, for instance, the hash of the program bytecode.
|
// Just a fake program identifier for now. In a real system it could be, for instance, the hash of the program bytecode.
|
||||||
val CASH_PROGRAM_ID = Cash()
|
val CASH_PROGRAM_ID = Cash()
|
||||||
//SecureHash.sha256("cash")
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple
|
* A cash transaction may split and merge money represented by a set of (issuer, depositRef) pairs, across multiple
|
||||||
@ -242,3 +238,24 @@ val Wallet.cashBalances: Map<Currency, Amount<Currency>> get() = states.
|
|||||||
groupBy { it.token.product }.
|
groupBy { it.token.product }.
|
||||||
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
|
// Collapse to Map<Currency, Amount> by summing all the amounts of the same currency together.
|
||||||
mapValues { it.value.map { Amount(it.quantity, it.token.product) }.sumOrThrow() }
|
mapValues { it.value.map { Amount(it.quantity, it.token.product) }.sumOrThrow() }
|
||||||
|
|
||||||
|
fun Cash.State.ownedBy(owner: PublicKey) = copy(owner = owner)
|
||||||
|
fun Cash.State.issuedBy(party: Party) = copy(amount = Amount(amount.quantity, issuanceDef.copy(issuer = deposit.copy(party = party))))
|
||||||
|
fun Cash.State.issuedBy(deposit: PartyAndReference) = copy(amount = Amount(amount.quantity, issuanceDef.copy(issuer = deposit)))
|
||||||
|
fun Cash.State.withDeposit(deposit: PartyAndReference): Cash.State = copy(amount = amount.copy(token = amount.token.copy(issuer = deposit)))
|
||||||
|
|
||||||
|
infix fun Cash.State.`owned by`(owner: PublicKey) = ownedBy(owner)
|
||||||
|
infix fun Cash.State.`issued by`(party: Party) = issuedBy(party)
|
||||||
|
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
|
||||||
|
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = withDeposit(deposit)
|
||||||
|
|
||||||
|
// Unit testing helpers. These could go in a separate file but it's hardly worth it for just a few functions.
|
||||||
|
|
||||||
|
/** A randomly generated key. */
|
||||||
|
val DUMMY_CASH_ISSUER_KEY by lazy { generateKeyPair() }
|
||||||
|
/** A dummy, randomly generated issuer party by the name of "Snake Oil Issuer" */
|
||||||
|
val DUMMY_CASH_ISSUER by lazy { Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public).ref(1) }
|
||||||
|
/** An extension property that lets you write 100.DOLLARS.CASH */
|
||||||
|
val Amount<Currency>.CASH: Cash.State get() = Cash.State(Amount(quantity, Issued(DUMMY_CASH_ISSUER, token)), NullPublicKey)
|
||||||
|
/** An extension property that lets you get a cash state from an issued token, under the [NullPublicKey] */
|
||||||
|
val Amount<Issued<Currency>>.STATE: Cash.State get() = Cash.State(this, NullPublicKey)
|
@ -1,15 +1,18 @@
|
|||||||
package com.r3corda.contracts.asset
|
package com.r3corda.contracts.asset
|
||||||
|
|
||||||
import com.google.common.annotations.VisibleForTesting
|
import com.google.common.annotations.VisibleForTesting
|
||||||
import com.r3corda.contracts.asset.FungibleAssetState
|
import com.r3corda.contracts.asset.Obligation.Lifecycle.NORMAL
|
||||||
import com.r3corda.contracts.asset.sumFungibleOrNull
|
|
||||||
import com.r3corda.core.contracts.*
|
import com.r3corda.core.contracts.*
|
||||||
|
import com.r3corda.core.crypto.NullPublicKey
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.SecureHash
|
import com.r3corda.core.crypto.SecureHash
|
||||||
import com.r3corda.core.crypto.toStringShort
|
import com.r3corda.core.crypto.toStringShort
|
||||||
import com.r3corda.core.random63BitValue
|
import com.r3corda.core.random63BitValue
|
||||||
|
import com.r3corda.core.testing.MINI_CORP
|
||||||
|
import com.r3corda.core.testing.TEST_TX_TIME
|
||||||
import com.r3corda.core.utilities.Emoji
|
import com.r3corda.core.utilities.Emoji
|
||||||
import com.r3corda.core.utilities.NonEmptySet
|
import com.r3corda.core.utilities.NonEmptySet
|
||||||
|
import com.r3corda.core.utilities.nonEmptySetOf
|
||||||
import java.security.PublicKey
|
import java.security.PublicKey
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
@ -812,3 +815,16 @@ fun <P> Iterable<ContractState>.sumObligationsOrNull(): Amount<P>?
|
|||||||
fun <P> Iterable<ContractState>.sumObligationsOrZero(product: P): Amount<P>
|
fun <P> Iterable<ContractState>.sumObligationsOrZero(product: P): Amount<P>
|
||||||
= filterIsInstance<Obligation.State<P>>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(product)
|
= filterIsInstance<Obligation.State<P>>().filter { it.lifecycle == Obligation.Lifecycle.NORMAL }.map { it.amount }.sumOrZero(product)
|
||||||
|
|
||||||
|
infix fun <T> Obligation.State<T>.at(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore))
|
||||||
|
infix fun <T> Obligation.IssuanceDefinition<T>.at(dueBefore: Instant) = copy(template = template.copy(dueBefore = dueBefore))
|
||||||
|
infix fun <T> Obligation.State<T>.between(parties: Pair<Party, PublicKey>) = copy(obligor = parties.first, beneficiary = parties.second)
|
||||||
|
infix fun <T> Obligation.State<T>.`owned by`(owner: PublicKey) = copy(beneficiary = owner)
|
||||||
|
infix fun <T> Obligation.State<T>.`issued by`(party: Party) = copy(obligor = party)
|
||||||
|
// For Java users:
|
||||||
|
fun <T> Obligation.State<T>.ownedBy(owner: PublicKey) = copy(beneficiary = owner)
|
||||||
|
fun <T> Obligation.State<T>.issuedBy(party: Party) = copy(obligor = party)
|
||||||
|
|
||||||
|
val Issued<Currency>.OBLIGATION_DEF: Obligation.StateTemplate<Currency>
|
||||||
|
get() = Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(this), TEST_TX_TIME)
|
||||||
|
val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency>
|
||||||
|
get() = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP, token.OBLIGATION_DEF, quantity, NullPublicKey)
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
package com.r3corda.contracts.testing
|
|
||||||
|
|
||||||
import com.r3corda.contracts.*
|
|
||||||
import com.r3corda.contracts.asset.Cash
|
|
||||||
import com.r3corda.contracts.asset.Obligation
|
|
||||||
import com.r3corda.core.contracts.Amount
|
|
||||||
import com.r3corda.core.contracts.ContractState
|
|
||||||
import com.r3corda.core.contracts.PartyAndReference
|
|
||||||
import com.r3corda.core.contracts.Issued
|
|
||||||
import com.r3corda.core.contracts.TransactionState
|
|
||||||
import com.r3corda.core.crypto.NullPublicKey
|
|
||||||
import com.r3corda.core.crypto.Party
|
|
||||||
import com.r3corda.core.crypto.generateKeyPair
|
|
||||||
import com.r3corda.core.testing.MINI_CORP
|
|
||||||
import com.r3corda.core.testing.TEST_TX_TIME
|
|
||||||
import com.r3corda.core.utilities.nonEmptySetOf
|
|
||||||
import java.security.PublicKey
|
|
||||||
import java.time.Instant
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
object JavaTestHelpers {
|
|
||||||
@JvmStatic fun ownedBy(state: Cash.State, owner: PublicKey) = state.copy(owner = owner)
|
|
||||||
@JvmStatic fun issuedBy(state: Cash.State, party: Party) = state.copy(amount = Amount(state.amount.quantity, state.issuanceDef.copy(issuer = state.deposit.copy(party = party))))
|
|
||||||
@JvmStatic fun issuedBy(state: Cash.State, deposit: PartyAndReference) = state.copy(amount = Amount(state.amount.quantity, state.issuanceDef.copy(issuer = deposit)))
|
|
||||||
@JvmStatic fun withNotary(state: Cash.State, notary: Party) = TransactionState(state, notary)
|
|
||||||
@JvmStatic fun withDeposit(state: Cash.State, deposit: PartyAndReference) = state.copy(amount = state.amount.copy(token = state.amount.token.copy(issuer = deposit)))
|
|
||||||
|
|
||||||
@JvmStatic fun <T> at(state: Obligation.State<T>, dueBefore: Instant) = state.copy(template = state.template.copy(dueBefore = dueBefore))
|
|
||||||
@JvmStatic fun <T> at(issuanceDef: Obligation.IssuanceDefinition<T>, dueBefore: Instant) = issuanceDef.copy(template = issuanceDef.template.copy(dueBefore = dueBefore))
|
|
||||||
@JvmStatic fun <T> between(state: Obligation.State<T>, parties: Pair<Party, PublicKey>) = state.copy(obligor = parties.first, beneficiary = parties.second)
|
|
||||||
@JvmStatic fun <T> ownedBy(state: Obligation.State<T>, owner: PublicKey) = state.copy(beneficiary = owner)
|
|
||||||
@JvmStatic fun <T> issuedBy(state: Obligation.State<T>, party: Party) = state.copy(obligor = party)
|
|
||||||
|
|
||||||
@JvmStatic fun ownedBy(state: CommercialPaper.State, owner: PublicKey) = state.copy(owner = owner)
|
|
||||||
@JvmStatic fun withNotary(state: CommercialPaper.State, notary: Party) = TransactionState(state, notary)
|
|
||||||
@JvmStatic fun ownedBy(state: ICommercialPaperState, new_owner: PublicKey): ICommercialPaperState = state.withOwner(new_owner)
|
|
||||||
|
|
||||||
@JvmStatic fun withNotary(state: ContractState, notary: Party) = TransactionState(state, notary)
|
|
||||||
|
|
||||||
@JvmStatic fun CASH(amount: Amount<Currency>) = Cash.State(
|
|
||||||
Amount(amount.quantity, Issued(DUMMY_CASH_ISSUER, amount.token)),
|
|
||||||
NullPublicKey)
|
|
||||||
@JvmStatic fun STATE(amount: Amount<Issued<Currency>>) = Cash.State(amount, NullPublicKey)
|
|
||||||
|
|
||||||
// Allows you to write 100.DOLLARS.OBLIGATION
|
|
||||||
@JvmStatic fun OBLIGATION_DEF(issued: Issued<Currency>)
|
|
||||||
= Obligation.StateTemplate(nonEmptySetOf(Cash().legalContractReference), nonEmptySetOf(issued), TEST_TX_TIME)
|
|
||||||
@JvmStatic fun OBLIGATION(amount: Amount<Issued<Currency>>) = Obligation.State(Obligation.Lifecycle.NORMAL, MINI_CORP,
|
|
||||||
OBLIGATION_DEF(amount.token), amount.quantity, NullPublicKey)
|
|
||||||
}
|
|
||||||
|
|
||||||
infix fun Cash.State.`owned by`(owner: PublicKey) = JavaTestHelpers.ownedBy(this, owner)
|
|
||||||
infix fun Cash.State.`issued by`(party: Party) = JavaTestHelpers.issuedBy(this, party)
|
|
||||||
infix fun Cash.State.`issued by`(deposit: PartyAndReference) = JavaTestHelpers.issuedBy(this, deposit)
|
|
||||||
infix fun Cash.State.`with notary`(notary: Party) = JavaTestHelpers.withNotary(this, notary)
|
|
||||||
infix fun Cash.State.`with deposit`(deposit: PartyAndReference): Cash.State = JavaTestHelpers.withDeposit(this, deposit)
|
|
||||||
|
|
||||||
infix fun <T> Obligation.State<T>.`at`(dueBefore: Instant) = JavaTestHelpers.at(this, dueBefore)
|
|
||||||
infix fun <T> Obligation.IssuanceDefinition<T>.`at`(dueBefore: Instant) = JavaTestHelpers.at(this, dueBefore)
|
|
||||||
infix fun <T> Obligation.State<T>.`between`(parties: Pair<Party, PublicKey>) = JavaTestHelpers.between(this, parties)
|
|
||||||
infix fun <T> Obligation.State<T>.`owned by`(owner: PublicKey) = JavaTestHelpers.ownedBy(this, owner)
|
|
||||||
infix fun <T> Obligation.State<T>.`issued by`(party: Party) = JavaTestHelpers.issuedBy(this, party)
|
|
||||||
|
|
||||||
infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = JavaTestHelpers.ownedBy(this, owner)
|
|
||||||
infix fun CommercialPaper.State.`with notary`(notary: Party) = JavaTestHelpers.withNotary(this, notary)
|
|
||||||
infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = JavaTestHelpers.ownedBy(this, new_owner)
|
|
||||||
|
|
||||||
infix fun ContractState.`with notary`(notary: Party) = JavaTestHelpers.withNotary(this, notary)
|
|
||||||
|
|
||||||
val DUMMY_CASH_ISSUER_KEY = generateKeyPair()
|
|
||||||
val DUMMY_CASH_ISSUER = Party("Snake Oil Issuer", DUMMY_CASH_ISSUER_KEY.public).ref(1)
|
|
||||||
/** Allows you to write 100.DOLLARS.CASH */
|
|
||||||
val Amount<Currency>.CASH: Cash.State get() = JavaTestHelpers.CASH(this)
|
|
||||||
val Amount<Issued<Currency>>.STATE: Cash.State get() = JavaTestHelpers.STATE(this)
|
|
||||||
|
|
||||||
/** Allows you to write 100.DOLLARS.CASH */
|
|
||||||
val Issued<Currency>.OBLIGATION_DEF: Obligation.StateTemplate<Currency> get() = JavaTestHelpers.OBLIGATION_DEF(this)
|
|
||||||
val Amount<Issued<Currency>>.OBLIGATION: Obligation.State<Currency> get() = JavaTestHelpers.OBLIGATION(this)
|
|
@ -5,15 +5,13 @@ import com.r3corda.core.serialization.OpaqueBytes;
|
|||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static com.r3corda.core.testing.JavaTestHelpers.*;
|
import static com.r3corda.core.testing.CoreTestUtils.*;
|
||||||
import static com.r3corda.core.contracts.JavaTestHelpers.*;
|
import static com.r3corda.core.contracts.ContractsDSL.*;
|
||||||
import static com.r3corda.contracts.testing.JavaTestHelpers.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL
|
* This is an incomplete Java replica of CashTests.kt to show how to use the Java test DSL
|
||||||
*/
|
*/
|
||||||
public class CashTestsJava {
|
public class CashTestsJava {
|
||||||
|
|
||||||
private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});
|
private OpaqueBytes defaultRef = new OpaqueBytes(new byte[]{1});
|
||||||
private PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef);
|
private PartyAndReference defaultIssuer = getMEGA_CORP().ref(defaultRef);
|
||||||
private Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), getDUMMY_PUBKEY_1());
|
private Cash.State inState = new Cash.State(issuedBy(DOLLARS(1000), defaultIssuer), getDUMMY_PUBKEY_1());
|
||||||
@ -43,7 +41,9 @@ public class CashTestsJava {
|
|||||||
});
|
});
|
||||||
tx.tweak(tw -> {
|
tx.tweak(tw -> {
|
||||||
tw.output(outState);
|
tw.output(outState);
|
||||||
tw.output(issuedBy(outState, getMINI_CORP()));
|
// issuedBy() can't be directly imported because it conflicts with other identically named functions
|
||||||
|
// with different overloads (for some reason).
|
||||||
|
tw.output(com.r3corda.contracts.asset.CashKt.issuedBy(outState, getMINI_CORP()));
|
||||||
tw.command(getDUMMY_PUBKEY_1(), new Cash.Commands.Move());
|
tw.command(getDUMMY_PUBKEY_1(), new Cash.Commands.Move());
|
||||||
return tw.failsWith("at least one asset input");
|
return tw.failsWith("at least one asset input");
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package com.r3corda.contracts
|
package com.r3corda.contracts
|
||||||
|
|
||||||
import com.r3corda.contracts.asset.Cash
|
import com.r3corda.contracts.asset.*
|
||||||
import com.r3corda.contracts.testing.*
|
|
||||||
import com.r3corda.core.contracts.*
|
import com.r3corda.core.contracts.*
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.SecureHash
|
import com.r3corda.core.crypto.SecureHash
|
||||||
@ -171,7 +170,7 @@ class CommercialPaperTestsGeneric {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : ContractState> cashOutputsToWallet(vararg outputs: TransactionState<T>): Pair<LedgerTransaction, List<StateAndRef<T>>> {
|
fun cashOutputsToWallet(vararg outputs: TransactionState<Cash.State>): Pair<LedgerTransaction, List<StateAndRef<Cash.State>>> {
|
||||||
val ltx = LedgerTransaction(emptyList(), listOf(*outputs), emptyList(), emptyList(), SecureHash.randomSHA256(), emptyList(), TransactionType.General())
|
val ltx = LedgerTransaction(emptyList(), listOf(*outputs), emptyList(), emptyList(), SecureHash.randomSHA256(), emptyList(), TransactionType.General())
|
||||||
return Pair(ltx, outputs.mapIndexed { index, state -> StateAndRef(state, StateRef(ltx.id, index)) })
|
return Pair(ltx, outputs.mapIndexed { index, state -> StateAndRef(state, StateRef(ltx.id, index)) })
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,5 @@
|
|||||||
package com.r3corda.contracts.asset
|
package com.r3corda.contracts.asset
|
||||||
|
|
||||||
import com.r3corda.contracts.testing.`issued by`
|
|
||||||
import com.r3corda.contracts.testing.`owned by`
|
|
||||||
import com.r3corda.contracts.testing.`with deposit`
|
|
||||||
import com.r3corda.contracts.testing.`with notary`
|
|
||||||
import com.r3corda.core.contracts.*
|
import com.r3corda.core.contracts.*
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.SecureHash
|
import com.r3corda.core.crypto.SecureHash
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@file:JvmName("ContractsDSL")
|
||||||
package com.r3corda.core.contracts
|
package com.r3corda.core.contracts
|
||||||
|
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
@ -17,34 +18,27 @@ import java.util.*
|
|||||||
|
|
||||||
//// Currencies ///////////////////////////////////////////////////////////////////////////////////////////////////////
|
//// Currencies ///////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
fun currency(code: String) = Currency.getInstance(code)
|
fun currency(code: String) = Currency.getInstance(code)!!
|
||||||
|
|
||||||
// Java interop
|
@JvmField val USD = currency("USD")
|
||||||
object JavaTestHelpers {
|
@JvmField val GBP = currency("GBP")
|
||||||
@JvmStatic val USD: Currency get() = currency("USD")
|
@JvmField val CHF = currency("CHF")
|
||||||
@JvmStatic val GBP: Currency get() = currency("GBP")
|
|
||||||
@JvmStatic val CHF: Currency get() = currency("CHF")
|
|
||||||
|
|
||||||
@JvmStatic fun DOLLARS(amount: Int) = Amount(amount.toLong() * 100, USD)
|
fun DOLLARS(amount: Int): Amount<Currency> = Amount(amount.toLong() * 100, USD)
|
||||||
@JvmStatic fun DOLLARS(amount: Double) = Amount((amount * 100).toLong(), USD)
|
fun DOLLARS(amount: Double): Amount<Currency> = Amount((amount * 100).toLong(), USD)
|
||||||
@JvmStatic fun POUNDS(amount: Int) = Amount(amount.toLong() * 100, GBP)
|
fun POUNDS(amount: Int): Amount<Currency> = Amount(amount.toLong() * 100, GBP)
|
||||||
@JvmStatic fun SWISS_FRANCS(amount: Int) = Amount(amount.toLong() * 100, CHF)
|
fun SWISS_FRANCS(amount: Int): Amount<Currency> = Amount(amount.toLong() * 100, CHF)
|
||||||
|
|
||||||
@JvmStatic fun issuedBy(currency: Currency, deposit: PartyAndReference) = Issued<Currency>(deposit, currency)
|
val Int.DOLLARS: Amount<Currency> get() = DOLLARS(this)
|
||||||
@JvmStatic fun issuedBy(amount: Amount<Currency>, deposit: PartyAndReference) = Amount(amount.quantity, issuedBy(amount.token, deposit))
|
val Double.DOLLARS: Amount<Currency> get() = DOLLARS(this)
|
||||||
}
|
val Int.POUNDS: Amount<Currency> get() = POUNDS(this)
|
||||||
|
val Int.SWISS_FRANCS: Amount<Currency> get() = SWISS_FRANCS(this)
|
||||||
|
|
||||||
val USD = JavaTestHelpers.USD
|
infix fun Currency.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
|
||||||
val GBP = JavaTestHelpers.GBP
|
infix fun Amount<Currency>.`issued by`(deposit: PartyAndReference) = issuedBy(deposit)
|
||||||
val CHF = JavaTestHelpers.CHF
|
infix fun Currency.issuedBy(deposit: PartyAndReference) = Issued<Currency>(deposit, this)
|
||||||
|
infix fun Amount<Currency>.issuedBy(deposit: PartyAndReference) = Amount(quantity, token.issuedBy(deposit))
|
||||||
|
|
||||||
val Int.DOLLARS: Amount<Currency> get() = JavaTestHelpers.DOLLARS(this)
|
|
||||||
val Double.DOLLARS: Amount<Currency> get() = JavaTestHelpers.DOLLARS(this)
|
|
||||||
val Int.POUNDS: Amount<Currency> get() = JavaTestHelpers.POUNDS(this)
|
|
||||||
val Int.SWISS_FRANCS: Amount<Currency> get() = JavaTestHelpers.SWISS_FRANCS(this)
|
|
||||||
|
|
||||||
infix fun Currency.`issued by`(deposit: PartyAndReference) = JavaTestHelpers.issuedBy(this, deposit)
|
|
||||||
infix fun Amount<Currency>.`issued by`(deposit: PartyAndReference) = JavaTestHelpers.issuedBy(this, deposit)
|
|
||||||
|
|
||||||
//// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
|
//// Requirements /////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
@ -108,13 +108,18 @@ data class TransactionState<out T : ContractState>(
|
|||||||
val data: T,
|
val data: T,
|
||||||
/** Identity of the notary that ensures the state is not used as an input to a transaction more than once */
|
/** Identity of the notary that ensures the state is not used as an input to a transaction more than once */
|
||||||
val notary: Party) {
|
val notary: Party) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the underlying state, replacing the notary field with the new value.
|
* Copies the underlying state, replacing the notary field with the new value.
|
||||||
* To replace the notary, we need an approval (signature) from _all_ participants of the [ContractState]
|
* To replace the notary, we need an approval (signature) from _all_ participants of the [ContractState]
|
||||||
*/
|
*/
|
||||||
fun withNewNotary(newNotary: Party) = TransactionState(this.data, newNotary)
|
fun withNotary(newNotary: Party) = TransactionState(this.data, newNotary)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Wraps the [ContractState] in a [TransactionState] object */
|
||||||
|
infix fun <T : ContractState> T.`with notary`(newNotary: Party) = withNotary(newNotary)
|
||||||
|
infix fun <T : ContractState> T.withNotary(newNotary: Party) = TransactionState(this, newNotary)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Marker interface for data classes that represent the issuance state for a contract. These are intended as templates
|
* Marker interface for data classes that represent the issuance state for a contract. These are intended as templates
|
||||||
* from which the state object is initialised.
|
* from which the state object is initialised.
|
||||||
|
120
core/src/main/kotlin/com/r3corda/core/testing/CoreTestUtils.kt
Normal file
120
core/src/main/kotlin/com/r3corda/core/testing/CoreTestUtils.kt
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
@file:Suppress("UNUSED_PARAMETER", "UNCHECKED_CAST")
|
||||||
|
@file:JvmName("CoreTestUtils")
|
||||||
|
package com.r3corda.core.testing
|
||||||
|
|
||||||
|
import com.google.common.base.Throwables
|
||||||
|
import com.google.common.net.HostAndPort
|
||||||
|
import com.r3corda.core.contracts.Attachment
|
||||||
|
import com.r3corda.core.contracts.StateRef
|
||||||
|
import com.r3corda.core.contracts.TransactionBuilder
|
||||||
|
import com.r3corda.core.crypto.DummyPublicKey
|
||||||
|
import com.r3corda.core.crypto.Party
|
||||||
|
import com.r3corda.core.crypto.SecureHash
|
||||||
|
import com.r3corda.core.crypto.generateKeyPair
|
||||||
|
import com.r3corda.core.node.services.IdentityService
|
||||||
|
import com.r3corda.core.node.services.StorageService
|
||||||
|
import com.r3corda.core.node.services.testing.MockIdentityService
|
||||||
|
import com.r3corda.core.node.services.testing.MockStorageService
|
||||||
|
import java.net.ServerSocket
|
||||||
|
import java.security.KeyPair
|
||||||
|
import java.security.PublicKey
|
||||||
|
import java.time.Instant
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JAVA INTEROP
|
||||||
|
* ------------
|
||||||
|
*
|
||||||
|
* Please keep the following points in mind when extending the Kotlin DSL:
|
||||||
|
*
|
||||||
|
* - Annotate functions with Kotlin defaults with @JvmOverloads. This produces the relevant overloads for Java.
|
||||||
|
* - Void closures in arguments are inconvenient in Java, use overloading to define non-closure variants as well.
|
||||||
|
* - Top-level vals are trickier. *DO NOT USE @JvmField at the top level!* It's surprisingly easy to
|
||||||
|
* introduce a static init cycle because of the way Kotlin compiles top-level things, which can cause
|
||||||
|
* non-deterministic behaviour, including your field not being initialized at all! Instead opt for a proper Kotlin
|
||||||
|
* val either with a custom @JvmStatic get() or a lazy delegate if the initialiser has side-effects. See examples below.
|
||||||
|
* - Infix functions work as regular ones from Java, but symbols with spaces in them don't! Define a camelCase variant
|
||||||
|
* as well.
|
||||||
|
* - varargs are exposed as array types in Java. Define overloads for common cases.
|
||||||
|
* - The Int.DOLLARS syntax doesn't work from Java. Use the DOLLARS(int) function instead.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// A dummy time at which we will be pretending test transactions are created.
|
||||||
|
val TEST_TX_TIME: Instant get() = Instant.parse("2015-04-17T12:00:00.00Z")
|
||||||
|
|
||||||
|
// A few dummy values for testing.
|
||||||
|
val MEGA_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val MEGA_CORP_PUBKEY: PublicKey get() = MEGA_CORP_KEY.public
|
||||||
|
|
||||||
|
val MINI_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val MINI_CORP_PUBKEY: PublicKey get() = MINI_CORP_KEY.public
|
||||||
|
|
||||||
|
val ORACLE_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val ORACLE_PUBKEY: PublicKey get() = ORACLE_KEY.public
|
||||||
|
|
||||||
|
val DUMMY_PUBKEY_1: PublicKey get() = DummyPublicKey("x1")
|
||||||
|
val DUMMY_PUBKEY_2: PublicKey get() = DummyPublicKey("x2")
|
||||||
|
|
||||||
|
val DUMMY_KEY_1: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val DUMMY_KEY_2: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val DUMMY_KEY_3: KeyPair by lazy { generateKeyPair() }
|
||||||
|
|
||||||
|
val ALICE_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val ALICE_PUBKEY: PublicKey get() = ALICE_KEY.public
|
||||||
|
val ALICE: Party get() = Party("Alice", ALICE_PUBKEY)
|
||||||
|
|
||||||
|
val BOB_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val BOB_PUBKEY: PublicKey get() = BOB_KEY.public
|
||||||
|
val BOB: Party get() = Party("Bob", BOB_PUBKEY)
|
||||||
|
|
||||||
|
val MEGA_CORP: Party get() = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
||||||
|
val MINI_CORP: Party get() = Party("MiniCorp", MINI_CORP_PUBKEY)
|
||||||
|
|
||||||
|
val DUMMY_NOTARY_KEY: KeyPair by lazy { generateKeyPair() }
|
||||||
|
val DUMMY_NOTARY: Party get() = Party("Notary Service", DUMMY_NOTARY_KEY.public)
|
||||||
|
|
||||||
|
val ALL_TEST_KEYS: List<KeyPair> get() = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
|
||||||
|
|
||||||
|
val MOCK_IDENTITY_SERVICE: MockIdentityService get() = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
|
||||||
|
|
||||||
|
fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0)
|
||||||
|
|
||||||
|
/** If an exception is thrown by the body, rethrows the root cause exception. */
|
||||||
|
inline fun <R> rootCauseExceptions(body: () -> R): R {
|
||||||
|
try {
|
||||||
|
return body()
|
||||||
|
} catch(e: Exception) {
|
||||||
|
throw Throwables.getRootCause(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun freeLocalHostAndPort(): HostAndPort {
|
||||||
|
val freePort = ServerSocket(0).use { it.localPort }
|
||||||
|
return HostAndPort.fromParts("localhost", freePort)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and tests a ledger built by the passed in dsl.
|
||||||
|
* @param identityService: The [IdentityService] to be used while building the ledger.
|
||||||
|
* @param storageService: The [StorageService] to be used for storing e.g. [Attachment]s.
|
||||||
|
* @param dsl: The dsl building the ledger.
|
||||||
|
*/
|
||||||
|
@JvmOverloads fun ledger(
|
||||||
|
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
||||||
|
storageService: StorageService = MockStorageService(),
|
||||||
|
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
||||||
|
): LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
||||||
|
val ledgerDsl = LedgerDSL(TestLedgerDSLInterpreter(identityService, storageService))
|
||||||
|
dsl(ledgerDsl)
|
||||||
|
return ledgerDsl
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a ledger with a single transaction, built by the passed in dsl.
|
||||||
|
*
|
||||||
|
* @see LedgerDSLInterpreter._transaction
|
||||||
|
*/
|
||||||
|
@JvmOverloads fun transaction(
|
||||||
|
transactionLabel: String? = null,
|
||||||
|
transactionBuilder: TransactionBuilder = TransactionBuilder(),
|
||||||
|
dsl: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail
|
||||||
|
) = ledger { this.transaction(transactionLabel, transactionBuilder, dsl) }
|
@ -7,7 +7,6 @@ import com.r3corda.core.crypto.SecureHash
|
|||||||
import com.r3corda.core.crypto.signWithECDSA
|
import com.r3corda.core.crypto.signWithECDSA
|
||||||
import com.r3corda.core.node.services.IdentityService
|
import com.r3corda.core.node.services.IdentityService
|
||||||
import com.r3corda.core.node.services.StorageService
|
import com.r3corda.core.node.services.StorageService
|
||||||
import com.r3corda.core.node.services.testing.MockStorageService
|
|
||||||
import com.r3corda.core.serialization.serialize
|
import com.r3corda.core.serialization.serialize
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
import java.security.KeyPair
|
import java.security.KeyPair
|
||||||
@ -41,24 +40,6 @@ import java.util.*
|
|||||||
* tests. Top level primitives [ledger] and [transaction] that bind the interpreter types are also defined here.
|
* tests. Top level primitives [ledger] and [transaction] that bind the interpreter types are also defined here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @see JavaTestHelpers.transaction
|
|
||||||
*/
|
|
||||||
fun transaction(
|
|
||||||
transactionLabel: String? = null,
|
|
||||||
transactionBuilder: TransactionBuilder = TransactionBuilder(),
|
|
||||||
dsl: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail
|
|
||||||
) = JavaTestHelpers.transaction(transactionLabel, transactionBuilder, dsl)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see JavaTestHelpers.ledger
|
|
||||||
*/
|
|
||||||
fun ledger(
|
|
||||||
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
|
||||||
storageService: StorageService = MockStorageService(),
|
|
||||||
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
|
||||||
) = JavaTestHelpers.ledger(identityService, storageService, dsl)
|
|
||||||
|
|
||||||
@Deprecated(
|
@Deprecated(
|
||||||
message = "ledger doesn't nest, use tweak",
|
message = "ledger doesn't nest, use tweak",
|
||||||
replaceWith = ReplaceWith("tweak"),
|
replaceWith = ReplaceWith("tweak"),
|
||||||
|
@ -1,145 +0,0 @@
|
|||||||
@file:Suppress("UNUSED_PARAMETER", "UNCHECKED_CAST")
|
|
||||||
|
|
||||||
package com.r3corda.core.testing
|
|
||||||
|
|
||||||
import com.google.common.base.Throwables
|
|
||||||
import com.google.common.net.HostAndPort
|
|
||||||
import com.r3corda.core.contracts.*
|
|
||||||
import com.r3corda.core.crypto.*
|
|
||||||
import com.r3corda.core.node.services.IdentityService
|
|
||||||
import com.r3corda.core.node.services.StorageService
|
|
||||||
import com.r3corda.core.node.services.testing.MockIdentityService
|
|
||||||
import com.r3corda.core.node.services.testing.MockStorageService
|
|
||||||
import java.net.ServerSocket
|
|
||||||
import java.security.KeyPair
|
|
||||||
import java.security.PublicKey
|
|
||||||
import java.time.Instant
|
|
||||||
|
|
||||||
/**
|
|
||||||
* JAVA INTEROP. Please keep the following points in mind when extending the Kotlin DSL
|
|
||||||
*
|
|
||||||
* - Annotate functions with Kotlin defaults with @JvmOverloads. This produces the relevant overloads for Java.
|
|
||||||
* - Void closures in arguments are inconvenient in Java, use overloading to define non-closure variants as well.
|
|
||||||
* - Top-level funs should be defined in a [JavaTestHelpers] object and annotated with @JvmStatic first and should be
|
|
||||||
* referred to from the global fun. This allows static importing of [JavaTestHelpers] in Java tests, which mimicks
|
|
||||||
* top-level funs.
|
|
||||||
* - Top-level vals are trickier. *DO NOT USE @JvmField INSIDE [JavaTestHelpers]*. It's surprisingly easy to
|
|
||||||
* introduce a static init cycle because of the way Kotlin compiles top-level things, which can cause
|
|
||||||
* non-deterministic behaviour, including your field not being initialized at all! Instead opt for a proper Kotlin
|
|
||||||
* val either with a custom @JvmStatic get() or a lazy delegate if the initialiser has side-effects See examples below.
|
|
||||||
* - Infix functions work as regular ones from Java, but symbols with spaces in them don't! Define a camelCase variant
|
|
||||||
* as well.
|
|
||||||
* - varargs are exposed as array types in Java. Define overloads for common cases.
|
|
||||||
* - The Int.DOLLARS syntax doesn't work from Java. To remedy add a @JvmStatic DOLLARS(Int) function to
|
|
||||||
* [JavaTestHelpers]
|
|
||||||
*/
|
|
||||||
object JavaTestHelpers {
|
|
||||||
// A dummy time at which we will be pretending test transactions are created.
|
|
||||||
@JvmStatic val TEST_TX_TIME: Instant get() = Instant.parse("2015-04-17T12:00:00.00Z")
|
|
||||||
|
|
||||||
// A few dummy values for testing.
|
|
||||||
@JvmStatic val MEGA_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val MEGA_CORP_PUBKEY: PublicKey get() = MEGA_CORP_KEY.public
|
|
||||||
|
|
||||||
@JvmStatic val MINI_CORP_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val MINI_CORP_PUBKEY: PublicKey get() = MINI_CORP_KEY.public
|
|
||||||
|
|
||||||
@JvmStatic val ORACLE_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val ORACLE_PUBKEY: PublicKey get() = ORACLE_KEY.public
|
|
||||||
|
|
||||||
@JvmStatic val DUMMY_PUBKEY_1: PublicKey get() = DummyPublicKey("x1")
|
|
||||||
@JvmStatic val DUMMY_PUBKEY_2: PublicKey get() = DummyPublicKey("x2")
|
|
||||||
|
|
||||||
@JvmStatic val DUMMY_KEY_1: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val DUMMY_KEY_2: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val DUMMY_KEY_3: KeyPair by lazy { generateKeyPair() }
|
|
||||||
|
|
||||||
@JvmStatic val ALICE_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val ALICE_PUBKEY: PublicKey get() = ALICE_KEY.public
|
|
||||||
@JvmStatic val ALICE: Party get() = Party("Alice", ALICE_PUBKEY)
|
|
||||||
|
|
||||||
@JvmStatic val BOB_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val BOB_PUBKEY: PublicKey get() = BOB_KEY.public
|
|
||||||
@JvmStatic val BOB: Party get() = Party("Bob", BOB_PUBKEY)
|
|
||||||
|
|
||||||
@JvmStatic val MEGA_CORP: Party get() = Party("MegaCorp", MEGA_CORP_PUBKEY)
|
|
||||||
@JvmStatic val MINI_CORP: Party get() = Party("MiniCorp", MINI_CORP_PUBKEY)
|
|
||||||
|
|
||||||
@JvmStatic val DUMMY_NOTARY_KEY: KeyPair by lazy { generateKeyPair() }
|
|
||||||
@JvmStatic val DUMMY_NOTARY: Party get() = Party("Notary Service", DUMMY_NOTARY_KEY.public)
|
|
||||||
|
|
||||||
@JvmStatic val ALL_TEST_KEYS: List<KeyPair> get() = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
|
|
||||||
|
|
||||||
@JvmStatic val MOCK_IDENTITY_SERVICE: MockIdentityService get() = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
|
|
||||||
|
|
||||||
@JvmStatic fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0)
|
|
||||||
|
|
||||||
/** If an exception is thrown by the body, rethrows the root cause exception. */
|
|
||||||
@JvmStatic inline fun <R> rootCauseExceptions(body: () -> R): R {
|
|
||||||
try {
|
|
||||||
return body()
|
|
||||||
} catch(e: Exception) {
|
|
||||||
throw Throwables.getRootCause(e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@JvmStatic fun freeLocalHostAndPort(): HostAndPort {
|
|
||||||
val freePort = ServerSocket(0).use { it.localPort }
|
|
||||||
return HostAndPort.fromParts("localhost", freePort)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates and tests a ledger built by the passed in dsl.
|
|
||||||
* @param identityService The [IdentityService] to be used while building the ledger.
|
|
||||||
* @param storageService The [StorageService] to be used for storing e.g. [Attachment]s.
|
|
||||||
* @param dsl The dsl building the ledger.
|
|
||||||
*/
|
|
||||||
@JvmStatic @JvmOverloads fun ledger(
|
|
||||||
identityService: IdentityService = MOCK_IDENTITY_SERVICE,
|
|
||||||
storageService: StorageService = MockStorageService(),
|
|
||||||
dsl: LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.() -> Unit
|
|
||||||
): LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter> {
|
|
||||||
val ledgerDsl = LedgerDSL(TestLedgerDSLInterpreter(identityService, storageService))
|
|
||||||
dsl(ledgerDsl)
|
|
||||||
return ledgerDsl
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a ledger with a single transaction, built by the passed in dsl.
|
|
||||||
* @see LedgerDSLInterpreter._transaction
|
|
||||||
*/
|
|
||||||
@JvmStatic @JvmOverloads fun transaction(
|
|
||||||
transactionLabel: String? = null,
|
|
||||||
transactionBuilder: TransactionBuilder = TransactionBuilder(),
|
|
||||||
dsl: TransactionDSL<TransactionDSLInterpreter>.() -> EnforceVerifyOrFail
|
|
||||||
) = ledger { this.transaction(transactionLabel, transactionBuilder, dsl) }
|
|
||||||
}
|
|
||||||
|
|
||||||
val TEST_TX_TIME = JavaTestHelpers.TEST_TX_TIME
|
|
||||||
val MEGA_CORP_KEY = JavaTestHelpers.MEGA_CORP_KEY
|
|
||||||
val MEGA_CORP_PUBKEY = JavaTestHelpers.MEGA_CORP_PUBKEY
|
|
||||||
val MINI_CORP_KEY = JavaTestHelpers.MINI_CORP_KEY
|
|
||||||
val MINI_CORP_PUBKEY = JavaTestHelpers.MINI_CORP_PUBKEY
|
|
||||||
val ORACLE_KEY = JavaTestHelpers.ORACLE_KEY
|
|
||||||
val ORACLE_PUBKEY = JavaTestHelpers.ORACLE_PUBKEY
|
|
||||||
val DUMMY_PUBKEY_1 = JavaTestHelpers.DUMMY_PUBKEY_1
|
|
||||||
val DUMMY_PUBKEY_2 = JavaTestHelpers.DUMMY_PUBKEY_2
|
|
||||||
val DUMMY_KEY_1 = JavaTestHelpers.DUMMY_KEY_1
|
|
||||||
val DUMMY_KEY_2 = JavaTestHelpers.DUMMY_KEY_2
|
|
||||||
val DUMMY_KEY_3 = JavaTestHelpers.DUMMY_KEY_3
|
|
||||||
val ALICE_KEY = JavaTestHelpers.ALICE_KEY
|
|
||||||
val ALICE_PUBKEY = JavaTestHelpers.ALICE_PUBKEY
|
|
||||||
val ALICE = JavaTestHelpers.ALICE
|
|
||||||
val BOB_KEY = JavaTestHelpers.BOB_KEY
|
|
||||||
val BOB_PUBKEY = JavaTestHelpers.BOB_PUBKEY
|
|
||||||
val BOB = JavaTestHelpers.BOB
|
|
||||||
val MEGA_CORP = JavaTestHelpers.MEGA_CORP
|
|
||||||
val MINI_CORP = JavaTestHelpers.MINI_CORP
|
|
||||||
val DUMMY_NOTARY_KEY = JavaTestHelpers.DUMMY_NOTARY_KEY
|
|
||||||
val DUMMY_NOTARY = JavaTestHelpers.DUMMY_NOTARY
|
|
||||||
val ALL_TEST_KEYS = JavaTestHelpers.ALL_TEST_KEYS
|
|
||||||
val MOCK_IDENTITY_SERVICE = JavaTestHelpers.MOCK_IDENTITY_SERVICE
|
|
||||||
|
|
||||||
fun generateStateRef() = JavaTestHelpers.generateStateRef()
|
|
||||||
fun freeLocalHostAndPort() = JavaTestHelpers.freeLocalHostAndPort()
|
|
||||||
inline fun <R> rootCauseExceptions(body: () -> R) = JavaTestHelpers.rootCauseExceptions(body)
|
|
@ -35,7 +35,7 @@ object NotaryChangeProtocol: AbstractStateReplacementProtocol<Party>() {
|
|||||||
|
|
||||||
override fun assembleTx(): Pair<SignedTransaction, List<PublicKey>> {
|
override fun assembleTx(): Pair<SignedTransaction, List<PublicKey>> {
|
||||||
val state = originalState.state
|
val state = originalState.state
|
||||||
val newState = state.withNewNotary(modification)
|
val newState = state.withNotary(modification)
|
||||||
val participants = state.data.participants
|
val participants = state.data.participants
|
||||||
val tx = TransactionType.NotaryChange.Builder().withItems(originalState, newState)
|
val tx = TransactionType.NotaryChange.Builder().withItems(originalState, newState)
|
||||||
tx.signWith(serviceHub.storageService.myLegalIdentityKey)
|
tx.signWith(serviceHub.storageService.myLegalIdentityKey)
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
package com.r3corda.node.internal.testing
|
|
||||||
|
|
||||||
import com.r3corda.core.contracts.StateAndRef
|
|
||||||
import com.r3corda.core.contracts.DummyContract
|
|
||||||
import com.r3corda.core.contracts.StateRef
|
|
||||||
import com.r3corda.core.contracts.TransactionState
|
|
||||||
import com.r3corda.core.contracts.TransactionType
|
|
||||||
import com.r3corda.core.crypto.Party
|
|
||||||
import com.r3corda.core.seconds
|
|
||||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
|
||||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
|
||||||
import com.r3corda.node.internal.AbstractNode
|
|
||||||
import java.time.Instant
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
fun issueState(node: AbstractNode): StateAndRef<*> {
|
|
||||||
val tx = DummyContract().generateInitial(node.info.identity.ref(0), Random().nextInt(), DUMMY_NOTARY)
|
|
||||||
tx.signWith(node.storage.myLegalIdentityKey)
|
|
||||||
tx.signWith(DUMMY_NOTARY_KEY)
|
|
||||||
val stx = tx.toSignedTransaction()
|
|
||||||
node.services.recordTransactions(listOf(stx))
|
|
||||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
|
||||||
}
|
|
||||||
|
|
||||||
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
|
|
||||||
val state = TransactionState(DummyContract.MultiOwnerState(0,
|
|
||||||
listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY)
|
|
||||||
val tx = TransactionType.NotaryChange.Builder().withItems(state)
|
|
||||||
tx.signWith(nodeA.storage.myLegalIdentityKey)
|
|
||||||
tx.signWith(nodeB.storage.myLegalIdentityKey)
|
|
||||||
tx.signWith(DUMMY_NOTARY_KEY)
|
|
||||||
val stx = tx.toSignedTransaction()
|
|
||||||
nodeA.services.recordTransactions(listOf(stx))
|
|
||||||
nodeB.services.recordTransactions(listOf(stx))
|
|
||||||
val stateAndRef = StateAndRef(state, StateRef(stx.id, 0))
|
|
||||||
return stateAndRef
|
|
||||||
}
|
|
||||||
|
|
||||||
fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> {
|
|
||||||
val tx = DummyContract().generateInitial(node.info.identity.ref(0), Random().nextInt(), notary)
|
|
||||||
tx.setTime(Instant.now(), notary, 30.seconds)
|
|
||||||
tx.signWith(node.storage.myLegalIdentityKey)
|
|
||||||
val stx = tx.toSignedTransaction(false)
|
|
||||||
node.services.recordTransactions(listOf(stx))
|
|
||||||
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
|
||||||
}
|
|
@ -2,10 +2,10 @@ package com.r3corda.node.messaging
|
|||||||
|
|
||||||
import com.google.common.util.concurrent.ListenableFuture
|
import com.google.common.util.concurrent.ListenableFuture
|
||||||
import com.r3corda.contracts.CommercialPaper
|
import com.r3corda.contracts.CommercialPaper
|
||||||
|
import com.r3corda.contracts.asset.CASH
|
||||||
import com.r3corda.contracts.asset.Cash
|
import com.r3corda.contracts.asset.Cash
|
||||||
import com.r3corda.contracts.testing.CASH
|
import com.r3corda.contracts.asset.`issued by`
|
||||||
import com.r3corda.contracts.testing.`issued by`
|
import com.r3corda.contracts.asset.`owned by`
|
||||||
import com.r3corda.contracts.testing.`owned by`
|
|
||||||
import com.r3corda.contracts.testing.fillWithSomeTestCash
|
import com.r3corda.contracts.testing.fillWithSomeTestCash
|
||||||
import com.r3corda.core.contracts.*
|
import com.r3corda.core.contracts.*
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
package com.r3corda.node.services
|
package com.r3corda.node.services
|
||||||
|
|
||||||
|
import com.r3corda.contracts.asset.CASH
|
||||||
import com.r3corda.contracts.asset.Cash
|
import com.r3corda.contracts.asset.Cash
|
||||||
import com.r3corda.contracts.testing.CASH
|
import com.r3corda.contracts.asset.`issued by`
|
||||||
import com.r3corda.contracts.testing.`issued by`
|
import com.r3corda.contracts.asset.`owned by`
|
||||||
import com.r3corda.contracts.testing.`owned by`
|
|
||||||
import com.r3corda.contracts.testing.`with notary`
|
|
||||||
import com.r3corda.core.bd
|
import com.r3corda.core.bd
|
||||||
import com.r3corda.core.contracts.DOLLARS
|
import com.r3corda.core.contracts.DOLLARS
|
||||||
import com.r3corda.core.contracts.Fix
|
import com.r3corda.core.contracts.Fix
|
||||||
import com.r3corda.core.contracts.TransactionType
|
import com.r3corda.core.contracts.TransactionType
|
||||||
|
import com.r3corda.core.contracts.`with notary`
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.generateKeyPair
|
import com.r3corda.core.crypto.generateKeyPair
|
||||||
import com.r3corda.core.testing.ALICE_PUBKEY
|
import com.r3corda.core.testing.ALICE_PUBKEY
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package com.r3corda.node.services
|
package com.r3corda.node.services
|
||||||
|
|
||||||
|
import com.r3corda.core.contracts.*
|
||||||
import com.r3corda.core.crypto.Party
|
import com.r3corda.core.crypto.Party
|
||||||
import com.r3corda.core.crypto.generateKeyPair
|
import com.r3corda.core.crypto.generateKeyPair
|
||||||
|
import com.r3corda.core.seconds
|
||||||
import com.r3corda.core.testing.DUMMY_NOTARY
|
import com.r3corda.core.testing.DUMMY_NOTARY
|
||||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
||||||
|
import com.r3corda.node.internal.AbstractNode
|
||||||
import com.r3corda.node.internal.testing.MockNetwork
|
import com.r3corda.node.internal.testing.MockNetwork
|
||||||
import com.r3corda.node.internal.testing.issueMultiPartyState
|
|
||||||
import com.r3corda.node.internal.testing.issueState
|
|
||||||
import com.r3corda.node.services.network.NetworkMapService
|
import com.r3corda.node.services.network.NetworkMapService
|
||||||
import com.r3corda.node.services.transactions.SimpleNotaryService
|
import com.r3corda.node.services.transactions.SimpleNotaryService
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
@ -15,6 +16,8 @@ import protocols.NotaryChangeProtocol
|
|||||||
import protocols.NotaryChangeProtocol.Instigator
|
import protocols.NotaryChangeProtocol.Instigator
|
||||||
import protocols.StateReplacementException
|
import protocols.StateReplacementException
|
||||||
import protocols.StateReplacementRefused
|
import protocols.StateReplacementRefused
|
||||||
|
import java.time.Instant
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ExecutionException
|
import java.util.concurrent.ExecutionException
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
@ -91,3 +94,35 @@ class NotaryChangeTests {
|
|||||||
// - Multiple states in a single "notary change" transaction
|
// - Multiple states in a single "notary change" transaction
|
||||||
// - Transaction contains additional states and commands with business logic
|
// - Transaction contains additional states and commands with business logic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun issueState(node: AbstractNode): StateAndRef<*> {
|
||||||
|
val tx = DummyContract().generateInitial(node.info.identity.ref(0), Random().nextInt(), DUMMY_NOTARY)
|
||||||
|
tx.signWith(node.storage.myLegalIdentityKey)
|
||||||
|
tx.signWith(DUMMY_NOTARY_KEY)
|
||||||
|
val stx = tx.toSignedTransaction()
|
||||||
|
node.services.recordTransactions(listOf(stx))
|
||||||
|
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
|
||||||
|
val state = TransactionState(DummyContract.MultiOwnerState(0,
|
||||||
|
listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY)
|
||||||
|
val tx = TransactionType.NotaryChange.Builder().withItems(state)
|
||||||
|
tx.signWith(nodeA.storage.myLegalIdentityKey)
|
||||||
|
tx.signWith(nodeB.storage.myLegalIdentityKey)
|
||||||
|
tx.signWith(DUMMY_NOTARY_KEY)
|
||||||
|
val stx = tx.toSignedTransaction()
|
||||||
|
nodeA.services.recordTransactions(listOf(stx))
|
||||||
|
nodeB.services.recordTransactions(listOf(stx))
|
||||||
|
val stateAndRef = StateAndRef(state, StateRef(stx.id, 0))
|
||||||
|
return stateAndRef
|
||||||
|
}
|
||||||
|
|
||||||
|
fun issueInvalidState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateAndRef<*> {
|
||||||
|
val tx = DummyContract().generateInitial(node.info.identity.ref(0), Random().nextInt(), notary)
|
||||||
|
tx.setTime(Instant.now(), notary, 30.seconds)
|
||||||
|
tx.signWith(node.storage.myLegalIdentityKey)
|
||||||
|
val stx = tx.toSignedTransaction(false)
|
||||||
|
node.services.recordTransactions(listOf(stx))
|
||||||
|
return StateAndRef(tx.outputStates().first(), StateRef(stx.id, 0))
|
||||||
|
}
|
||||||
|
@ -7,7 +7,6 @@ import com.r3corda.core.testing.DUMMY_NOTARY
|
|||||||
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
||||||
import com.r3corda.core.testing.MINI_CORP_KEY
|
import com.r3corda.core.testing.MINI_CORP_KEY
|
||||||
import com.r3corda.node.internal.testing.MockNetwork
|
import com.r3corda.node.internal.testing.MockNetwork
|
||||||
import com.r3corda.node.internal.testing.issueState
|
|
||||||
import com.r3corda.node.services.network.NetworkMapService
|
import com.r3corda.node.services.network.NetworkMapService
|
||||||
import com.r3corda.node.services.transactions.SimpleNotaryService
|
import com.r3corda.node.services.transactions.SimpleNotaryService
|
||||||
import com.r3corda.protocols.NotaryError
|
import com.r3corda.protocols.NotaryError
|
||||||
|
@ -8,8 +8,6 @@ import com.r3corda.core.testing.DUMMY_NOTARY_KEY
|
|||||||
import com.r3corda.core.testing.MEGA_CORP_KEY
|
import com.r3corda.core.testing.MEGA_CORP_KEY
|
||||||
import com.r3corda.core.testing.MINI_CORP_KEY
|
import com.r3corda.core.testing.MINI_CORP_KEY
|
||||||
import com.r3corda.node.internal.testing.MockNetwork
|
import com.r3corda.node.internal.testing.MockNetwork
|
||||||
import com.r3corda.node.internal.testing.issueInvalidState
|
|
||||||
import com.r3corda.node.internal.testing.issueState
|
|
||||||
import com.r3corda.node.services.network.NetworkMapService
|
import com.r3corda.node.services.network.NetworkMapService
|
||||||
import com.r3corda.node.services.transactions.ValidatingNotaryService
|
import com.r3corda.node.services.transactions.ValidatingNotaryService
|
||||||
import com.r3corda.protocols.NotaryError
|
import com.r3corda.protocols.NotaryError
|
||||||
|
Loading…
Reference in New Issue
Block a user