Change references to 'wallet' with 'vault'

This commit is contained in:
Ross Nicoll 2016-09-19 11:32:38 +01:00
parent ae4513c8eb
commit ebda724f14
38 changed files with 252 additions and 250 deletions

View File

@ -17,7 +17,7 @@ class EventGenerator(
val notary: Party
) {
private var wallet = listOf<StateAndRef<Cash.State>>()
private var vault = listOf<StateAndRef<Cash.State>>()
val issuerGenerator =
Generator.pickOne(parties).combine(Generator.intRange(0, 1)) { party, ref -> party.ref(ref.toByte()) }
@ -42,19 +42,19 @@ class EventGenerator(
val consumedGenerator: Generator<Set<StateRef>> = Generator.frequency(
0.7 to Generator.pure(setOf()),
0.3 to Generator.impure { wallet }.bind { states ->
0.3 to Generator.impure { vault }.bind { states ->
Generator.sampleBernoulli(states, 0.2).map { someStates ->
val consumedSet = someStates.map { it.ref }.toSet()
wallet = wallet.filter { it.ref !in consumedSet }
vault = vault.filter { it.ref !in consumedSet }
consumedSet
}
}
)
val producedGenerator: Generator<Set<StateAndRef<ContractState>>> = Generator.frequency(
// 0.1 to Generator.pure(setOf())
0.9 to Generator.impure { wallet }.bind { states ->
0.9 to Generator.impure { vault }.bind { states ->
Generator.replicate(2, cashStateGenerator).map {
wallet = states + it
vault = states + it
it.toSet()
}
}

View File

@ -304,8 +304,8 @@ public class JavaCommercialPaper implements Contract {
return new TransactionType.General.Builder(notary).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 {
new Cash().generateSpend(tx, StructuresKt.withoutIssuer(paper.getState().getData().getFaceValue()), paper.getState().getData().getOwner(), wallet, null);
public void generateRedeem(TransactionBuilder tx, StateAndRef<State> paper, List<StateAndRef<Cash.State>> vault) throws InsufficientBalanceException {
new Cash().generateSpend(tx, StructuresKt.withoutIssuer(paper.getState().getData().getFaceValue()), paper.getState().getData().getOwner(), vault, null);
tx.addInputState(paper);
tx.addCommand(new Command(new Commands.Redeem(), paper.getState().getData().getOwner()));
}

View File

@ -187,13 +187,13 @@ class CommercialPaper : Contract {
* to redeem the paper. We must therefore send enough money to the key that owns the paper to satisfy the face
* value, and then ensure the paper is removed from the ledger.
*
* @throws InsufficientBalanceException if the wallet doesn't contain enough money to pay the redeemer.
* @throws InsufficientBalanceException if the vault doesn't contain enough money to pay the redeemer.
*/
@Throws(InsufficientBalanceException::class)
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: List<StateAndRef<Cash.State>>) {
// Add the cash movement using the states in our wallet.
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, vault: List<StateAndRef<Cash.State>>) {
// Add the cash movement using the states in our vault.
val amount = paper.state.data.faceValue.let { amount -> Amount(amount.quantity, amount.token.product) }
Cash().generateSpend(tx, amount, paper.state.data.owner, wallet)
Cash().generateSpend(tx, amount, paper.state.data.owner, vault)
tx.addInputState(paper)
tx.addCommand(CommercialPaper.Commands.Redeem(), paper.state.data.owner)
}

View File

@ -8,7 +8,7 @@ import com.r3corda.core.crypto.NullPublicKey
import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.utilities.Emoji
import java.security.PublicKey
@ -125,10 +125,10 @@ class CommercialPaperLegacy : Contract {
}
@Throws(InsufficientBalanceException::class)
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, wallet: Wallet) {
// Add the cash movement using the states in our wallet.
fun generateRedeem(tx: TransactionBuilder, paper: StateAndRef<State>, vault: Vault) {
// Add the cash movement using the states in our vault.
Cash().generateSpend(tx, paper.state.data.faceValue.withoutIssuer(),
paper.state.data.owner, wallet.statesOfType<Cash.State>())
paper.state.data.owner, vault.statesOfType<Cash.State>())
tx.addInputState(paper)
tx.addCommand(Command(Commands.Redeem(), paper.state.data.owner))
}

View File

@ -6,7 +6,7 @@ import com.r3corda.contracts.clause.NoZeroSizedOutputs
import com.r3corda.core.contracts.*
import com.r3corda.core.contracts.clauses.*
import com.r3corda.core.crypto.*
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.transactions.TransactionBuilder
import com.r3corda.core.utilities.Emoji
import java.math.BigInteger
@ -175,7 +175,7 @@ fun Iterable<ContractState>.sumCashOrZero(currency: Issued<Currency>): Amount<Is
* Returns a map of how much cash we have in each currency, ignoring details like issuer. Note: currencies for
* which we have no cash evaluate to null (not present in map), not 0.
*/
val Wallet.cashBalances: Map<Currency, Amount<Currency>> get() = states.
val Vault.cashBalances: Map<Currency, Amount<Currency>> get() = states.
// Select the states we own which are cash, ignore the rest, take the amounts.
mapNotNull { (it.state.data as? Cash.State)?.amount }.
// Turn into a Map<Currency, List<Amount>> like { GBP -> (£100, £500, etc), USD -> ($2000, $50) }

View File

@ -50,9 +50,9 @@ abstract class OnLedgerAsset<T : Any, C: CommandData, S : FungibleAsset<T>> : Co
/**
* Generate a transaction that consumes one or more of the given input states to move assets to the given pubkey.
* Note that the wallet list is not updated: it's up to you to do that.
* Note that the vault is not updated: it's up to you to do that.
*
* @param onlyFromParties if non-null, the wallet will be filtered to only include asset states issued by the set
* @param onlyFromParties if non-null, the asset states will be filtered to only include those issued by the set
* of given parties. This can be useful if the party you're trying to pay has expectations
* about which type of asset claims they are willing to accept.
*/

View File

@ -87,9 +87,9 @@ abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T :
/**
* Generate a transaction that consumes one or more of the given input states to move assets to the given pubkey.
* Note that the wallet list is not updated: it's up to you to do that.
* Note that the vault is not updated: it's up to you to do that.
*
* @param onlyFromParties if non-null, the wallet will be filtered to only include asset states issued by the set
* @param onlyFromParties if non-null, the asset states will be filtered to only include those issued by the set
* of given parties. This can be useful if the party you're trying to pay has expectations
* about which type of asset claims they are willing to accept.
*/
@ -106,7 +106,7 @@ abstract class AbstractConserveAmount<S : FungibleAsset<T>, C : CommandData, T :
// This code is analogous to the Wallet.send() set of methods in bitcoinj, and has the same general outline.
//
// First we must select a set of asset states (which for convenience we will call 'coins' here, as in bitcoinj).
// The input states can be considered our "wallet", and may consist of different products, and with different
// The input states can be considered our "vault", and may consist of different products, and with different
// issuers and deposits.
//
// Coin selection is a complex problem all by itself and many different approaches can be used. It is easily

View File

@ -1,4 +1,4 @@
@file:JvmName("WalletFiller")
@file:JvmName("VaultFiller")
package com.r3corda.contracts.testing
import com.r3corda.contracts.asset.Cash
@ -10,7 +10,7 @@ import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.contracts.TransactionType
import com.r3corda.core.crypto.Party
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.serialization.OpaqueBytes
import com.r3corda.core.utilities.DUMMY_NOTARY
import java.security.PublicKey
@ -19,13 +19,13 @@ import java.util.*
/**
* Creates a random set of between (by default) 3 and 10 cash states that add up to the given amount and adds them
* to the wallet. This is intended for unit tests. The cash is issued by [DUMMY_CASH_ISSUER] and owned by the legal
* to the vault. This is intended for unit tests. The cash is issued by [DUMMY_CASH_ISSUER] and owned by the legal
* identity key from the storage service.
*
* The service hub needs to provide at least a key management service and a storage service.
*
* @param outputNotary the notary to use for output states. The transaction is NOT signed by this notary.
* @return a wallet object that represents the generated states (it will NOT be the full wallet from the service hub!).
* @return a vault object that represents the generated states (it will NOT be the full vault from the service hub!).
*/
fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
outputNotary: Party = DUMMY_NOTARY,
@ -33,7 +33,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
atMostThisManyStates: Int = 10,
rng: Random = Random(),
ref: OpaqueBytes = OpaqueBytes(ByteArray(1, { 1 })),
ownedBy: PublicKey? = null): Wallet {
ownedBy: PublicKey? = null): Vault {
val amounts = calculateRandomlySizedAmounts(howMuch, atLeastThisManyStates, atMostThisManyStates, rng)
val myKey: PublicKey = ownedBy ?: storageService.myLegalIdentityKey.public
@ -55,7 +55,7 @@ fun ServiceHub.fillWithSomeTestCash(howMuch: Amount<Currency>,
stx.tx.outputs.indices.map { i -> stx.tx.outRef<Cash.State>(i) }
}
return Wallet(states)
return Vault(states)
}
private fun calculateRandomlySizedAmounts(howMuch: Amount<Currency>, min: Int, max: Int, rng: Random): LongArray {

View File

@ -243,7 +243,7 @@ object TwoPartyTradeProtocol {
private fun assembleSharedTX(tradeRequest: SellerTradeInfo): Pair<TransactionBuilder, List<PublicKey>> {
val ptx = TransactionType.General.Builder(notary)
// 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 wallet = serviceHub.vaultService.currentVault
val cashStates = wallet.statesOfType<Cash.State>()
val cashSigningPubKeys = Cash().generateSpend(ptx, tradeRequest.price, tradeRequest.sellerOwnerKey, cashStates)
// Add inputs/outputs/a command for the movement of the asset.

View File

@ -191,7 +191,7 @@ class CommercialPaperTestsGeneric {
}
}
fun cashOutputsToWallet(vararg outputs: TransactionState<Cash.State>): Pair<LedgerTransaction, List<StateAndRef<Cash.State>>> {
fun cashOutputsToVault(vararg outputs: TransactionState<Cash.State>): Pair<LedgerTransaction, List<StateAndRef<Cash.State>>> {
val ltx = LedgerTransaction(emptyList(), listOf(*outputs), emptyList(), emptyList(), SecureHash.randomSHA256(), null, emptyList(), null, TransactionType.General())
return Pair(ltx, outputs.mapIndexed { index, state -> StateAndRef(state, StateRef(ltx.id, index)) })
}
@ -199,14 +199,14 @@ class CommercialPaperTestsGeneric {
@Test
fun `issue move and then redeem`() {
val aliceServices = MockServices()
val alicesWallet = aliceServices.fillWithSomeTestCash(9000.DOLLARS)
val alicesVault = aliceServices.fillWithSomeTestCash(9000.DOLLARS)
val bigCorpServices = MockServices()
val bigCorpWallet = bigCorpServices.fillWithSomeTestCash(13000.DOLLARS)
val bigCorpVault = bigCorpServices.fillWithSomeTestCash(13000.DOLLARS)
// Propagate the cash transactions to each side.
aliceServices.recordTransactions(bigCorpWallet.states.map { bigCorpServices.storageService.validatedTransactions.getTransaction(it.ref.txhash)!! })
bigCorpServices.recordTransactions(alicesWallet.states.map { aliceServices.storageService.validatedTransactions.getTransaction(it.ref.txhash)!! })
aliceServices.recordTransactions(bigCorpVault.states.map { bigCorpServices.storageService.validatedTransactions.getTransaction(it.ref.txhash)!! })
bigCorpServices.recordTransactions(alicesVault.states.map { aliceServices.storageService.validatedTransactions.getTransaction(it.ref.txhash)!! })
// BigCorp™ issues $10,000 of commercial paper, to mature in 30 days, owned initially by itself.
val faceValue = 10000.DOLLARS `issued by` DUMMY_CASH_ISSUER
@ -221,7 +221,7 @@ class CommercialPaperTestsGeneric {
// Alice pays $9000 to BigCorp to own some of their debt.
val moveTX: SignedTransaction = run {
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
Cash().generateSpend(ptx, 9000.DOLLARS, bigCorpServices.key.public, alicesWallet.statesOfType<Cash.State>())
Cash().generateSpend(ptx, 9000.DOLLARS, bigCorpServices.key.public, alicesVault.statesOfType<Cash.State>())
CommercialPaper().generateMove(ptx, issueTX.tx.outRef(0), aliceServices.key.public)
ptx.signWith(bigCorpServices.key)
ptx.signWith(aliceServices.key)
@ -232,7 +232,7 @@ class CommercialPaperTestsGeneric {
fun makeRedeemTX(time: Instant): SignedTransaction {
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
ptx.setTime(time, 30.seconds)
CommercialPaper().generateRedeem(ptx, moveTX.tx.outRef(1), bigCorpWallet.statesOfType<Cash.State>())
CommercialPaper().generateRedeem(ptx, moveTX.tx.outRef(1), bigCorpVault.statesOfType<Cash.State>())
ptx.signWith(aliceServices.key)
ptx.signWith(bigCorpServices.key)
ptx.signWith(DUMMY_NOTARY_KEY)

View File

@ -220,18 +220,18 @@ data class ScheduledActivity(val logicRef: ProtocolLogicRef, override val schedu
/**
* A state that evolves by superseding itself, all of which share the common "linearId".
*
* This simplifies the job of tracking the current version of certain types of state in e.g. a wallet.
* This simplifies the job of tracking the current version of certain types of state in e.g. a vault.
*/
interface LinearState: ContractState {
/**
* Unique id shared by all LinearState states throughout history within the wallets of all parties.
* Unique id shared by all LinearState states throughout history within the vaults of all parties.
* Verify methods should check that one input and one output share the id in a transaction,
* except at issuance/termination.
*/
val linearId: UniqueIdentifier
/**
* True if this should be tracked by our wallet(s).
* True if this should be tracked by our vault(s).
* */
fun isRelevant(ourKeys: Set<PublicKey>): Boolean
@ -328,7 +328,7 @@ data class StateRef(val txhash: SecureHash, val index: Int) {
override fun toString() = "$txhash($index)"
}
/** A StateAndRef is simply a (state, ref) pair. For instance, a wallet (which holds available assets) contains these. */
/** A StateAndRef is simply a (state, ref) pair. For instance, a vault (which holds available assets) contains these. */
data class StateAndRef<out T : ContractState>(val state: TransactionState<T>, val ref: StateRef)
/** Filters a list of [StateAndRef] objects according to the type of the states */

View File

@ -31,7 +31,7 @@ data class TransactionForContract(val inputs: List<ContractState>,
* The purpose of this function is to simplify the writing of verification logic for transactions that may contain
* similar but unrelated state evolutions which need to be checked independently. Consider a transaction that
* simultaneously moves both dollars and euros (e.g. is an atomic FX trade). There may be multiple dollar inputs and
* multiple dollar outputs, depending on things like how fragmented the owners wallet is and whether various privacy
* multiple dollar outputs, depending on things like how fragmented the owner's vault is and whether various privacy
* techniques are in use. The quantity of dollars on the output side must sum to the same as on the input side, to
* ensure no money is being lost track of. This summation and checking must be repeated independently for each
* currency. To solve this, you would use groupStates with a type of Cash.State and a selector that returns the

View File

@ -19,7 +19,7 @@ import java.time.Clock
* state from being serialized in checkpoints.
*/
interface ServiceHub {
val walletService: WalletService
val vaultService: VaultService
val keyManagementService: KeyManagementService
val identityService: IdentityService
val storageService: StorageService
@ -30,7 +30,7 @@ interface ServiceHub {
/**
* Given a list of [SignedTransaction]s, writes them to the local storage for validated transactions and then
* sends them to the wallet for further processing.
* sends them to the vault for further processing.
*
* @param txs The transactions to record.
*/
@ -38,7 +38,7 @@ interface ServiceHub {
/**
* Given some [SignedTransaction]s, writes them to the local storage for validated transactions and then
* sends them to the wallet for further processing.
* sends them to the vault for further processing.
*
* @param txs The transactions to record.
*/

View File

@ -21,9 +21,9 @@ val DEFAULT_SESSION_ID = 0L
*/
/**
* A wallet (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance,
* because we own them. This class represents an immutable, stable state of a wallet: it is guaranteed not to
* change out from underneath you, even though the canonical currently-best-known wallet may change as we learn
* A vault (name may be temporary) wraps a set of states that are useful for us to keep track of, for instance,
* because we own them. This class represents an immutable, stable state of a vault: it is guaranteed not to
* change out from underneath you, even though the canonical currently-best-known vault may change as we learn
* about new transactions from our peers and generate new transactions that consume states ourselves.
*
* This abstract class has no references to Cash contracts.
@ -32,16 +32,16 @@ val DEFAULT_SESSION_ID = 0L
* Active means they haven't been consumed yet (or we don't know about it).
* Relevant means they contain at least one of our pubkeys.
*/
class Wallet(val states: Iterable<StateAndRef<ContractState>>) {
class Vault(val states: Iterable<StateAndRef<ContractState>>) {
@Suppress("UNCHECKED_CAST")
inline fun <reified T : ContractState> statesOfType() = states.filter { it.state.data is T } as List<StateAndRef<T>>
/**
* Represents an update observed by the Wallet that will be notified to observers. Include the [StateRef]s of
* Represents an update observed by the vault that will be notified to observers. Include the [StateRef]s of
* transaction outputs that were consumed (inputs) and the [ContractState]s produced (outputs) to/by the transaction
* or transactions observed and the Wallet.
* or transactions observed and the vault.
*
* If the Wallet observes multiple transactions simultaneously, where some transactions consume the outputs of some of the
* If the vault observes multiple transactions simultaneously, where some transactions consume the outputs of some of the
* other transactions observed, then the changes are observed "net" of those.
*/
data class Update(val consumed: Set<StateRef>, val produced: Set<StateAndRef<ContractState>>) {
@ -54,7 +54,7 @@ class Wallet(val states: Iterable<StateAndRef<ContractState>>) {
operator fun plus(rhs: Update): Update {
val previouslyProduced = produced.map { it.ref }
val previouslyConsumed = consumed
val combined = Wallet.Update(
val combined = Vault.Update(
previouslyConsumed + (rhs.consumed - previouslyProduced),
// The ordering below matters to preserve ordering of consumed/produced Sets when they are insertion order dependent implementations.
produced.filter { it.ref !in rhs.consumed }.toSet() + rhs.produced)
@ -79,19 +79,19 @@ class Wallet(val states: Iterable<StateAndRef<ContractState>>) {
}
/**
* A [WalletService] is responsible for securely and safely persisting the current state of a wallet to storage. The
* wallet service vends immutable snapshots of the current wallet for working with: if you build a transaction based
* on a wallet that isn't current, be aware that it may end up being invalid if the states that were used have been
* A [VaultService] is responsible for securely and safely persisting the current state of a vault to storage. The
* vault service vends immutable snapshots of the current vault for working with: if you build a transaction based
* on a vault that isn't current, be aware that it may end up being invalid if the states that were used have been
* consumed by someone else first!
*
* Note that transactions we've seen are held by the storage service, not the wallet.
* Note that transactions we've seen are held by the storage service, not the vault.
*/
interface WalletService {
interface VaultService {
/**
* Returns a read-only snapshot of the wallet at the time the call is made. Note that if you consume states or
* keys in this wallet, you must inform the wallet service so it can update its internal state.
* Returns a read-only snapshot of the vault at the time the call is made. Note that if you consume states or
* keys in this vault, you must inform the vault service so it can update its internal state.
*/
val currentWallet: Wallet
val currentVault: Vault
/**
* Returns a snapshot of the heads of LinearStates.
@ -107,34 +107,34 @@ interface WalletService {
}
fun statesForRefs(refs: List<StateRef>): Map<StateRef, TransactionState<*>?> {
val refsToStates = currentWallet.states.associateBy { it.ref }
val refsToStates = currentVault.states.associateBy { it.ref }
return refs.associateBy({ it }, { refsToStates[it]?.state })
}
/**
* Possibly update the wallet by marking as spent states that these transactions consume, and adding any relevant
* Possibly update the vault by marking as spent states that these transactions consume, and adding any relevant
* new states that they create. You should only insert transactions that have been successfully verified here!
*
* Returns the new wallet that resulted from applying the transactions (note: it may quickly become out of date).
* Returns the new vault that resulted from applying the transactions (note: it may quickly become out of date).
*
* TODO: Consider if there's a good way to enforce the must-be-verified requirement in the type system.
*/
fun notifyAll(txns: Iterable<WireTransaction>): Wallet
fun notifyAll(txns: Iterable<WireTransaction>): Vault
/** Same as notifyAll but with a single transaction. */
fun notify(tx: WireTransaction): Wallet = notifyAll(listOf(tx))
fun notify(tx: WireTransaction): Vault = notifyAll(listOf(tx))
/**
* Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate
* the update.
* Get a synchronous Observable of updates. When observations are pushed to the Observer, the vault will already
* incorporate the update.
*/
val updates: rx.Observable<Wallet.Update>
val updates: rx.Observable<Vault.Update>
/**
* Provide a [Future] for when a [StateRef] is consumed, which can be very useful in building tests.
*/
fun whenConsumed(ref: StateRef): ListenableFuture<Wallet.Update> {
val future = SettableFuture.create<Wallet.Update>()
fun whenConsumed(ref: StateRef): ListenableFuture<Vault.Update> {
val future = SettableFuture.create<Vault.Update>()
updates.filter { ref in it.consumed }.first().subscribe {
future.set(it)
}
@ -142,7 +142,7 @@ interface WalletService {
}
}
inline fun <reified T : LinearState> WalletService.linearHeadsOfType() = linearHeadsOfType_(T::class.java)
inline fun <reified T : LinearState> VaultService.linearHeadsOfType() = linearHeadsOfType_(T::class.java)
/**
* The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,
@ -206,7 +206,7 @@ interface TxWritableStorageService : StorageService {
*
* If the point in time is in the past, the expectation is that the activity will happen shortly after it is scheduled.
*
* The main consumer initially is an observer of the wallet to schedule activities based on transactions as they are
* The main consumer initially is an observer of the vault to schedule activities based on transactions as they are
* recorded.
*/
interface SchedulerService {

View File

@ -13,8 +13,8 @@ interface ReadOnlyTransactionStorage {
fun getTransaction(id: SecureHash): SignedTransaction?
/**
* Get a synchronous Observable of updates. When observations are pushed to the Observer, the Wallet will already incorporate
* the update.
* Get a synchronous Observable of updates. When observations are pushed to the Observer, the vault will already
* incorporate the update.
*/
val updates: rx.Observable<SignedTransaction>
}

View File

@ -4,8 +4,8 @@ import com.r3corda.core.ThreadBox
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.WalletService
import com.r3corda.core.node.services.Vault
import com.r3corda.core.node.services.VaultService
import com.r3corda.core.serialization.SingletonSerializeAsToken
import com.r3corda.core.transactions.WireTransaction
import com.r3corda.core.utilities.loggerFor
@ -17,88 +17,88 @@ import java.util.*
import javax.annotation.concurrent.ThreadSafe
/**
* This class implements a simple, in memory wallet that tracks states that are owned by us, and also has a convenience
* method to auto-generate some self-issued cash states that can be used for test trading. A real wallet would persist
* states relevant to us into a database and once such a wallet is implemented, this scaffolding can be removed.
* This class implements a simple, in memory vault that tracks states that are owned by us, and also has a convenience
* method to auto-generate some self-issued cash states that can be used for test trading. A real vault would persist
* states relevant to us into a database and once such a vault is implemented, this scaffolding can be removed.
*/
@ThreadSafe
open class InMemoryWalletService(protected val services: ServiceHub) : SingletonSerializeAsToken(), WalletService {
open protected val log = loggerFor<InMemoryWalletService>()
open class InMemoryVaultService(protected val services: ServiceHub) : SingletonSerializeAsToken(), VaultService {
open protected val log = loggerFor<InMemoryVaultService>()
// Variables inside InnerState are protected with a lock by the ThreadBox and aren't in scope unless you're
// inside mutex.locked {} code block. So we can't forget to take the lock unless we accidentally leak a reference
// to wallet somewhere.
// to vault somewhere.
protected class InnerState {
var wallet = Wallet(emptyList<StateAndRef<ContractState>>())
var vault = Vault(emptyList<StateAndRef<ContractState>>())
}
protected val mutex = ThreadBox(InnerState())
override val currentWallet: Wallet get() = mutex.locked { wallet }
override val currentVault: Vault get() = mutex.locked { vault }
private val _updatesPublisher = PublishSubject.create<Wallet.Update>()
private val _updatesPublisher = PublishSubject.create<Vault.Update>()
override val updates: Observable<Wallet.Update>
override val updates: Observable<Vault.Update>
get() = _updatesPublisher
/**
* Returns a snapshot of the heads of LinearStates.
*/
override val linearHeads: Map<UniqueIdentifier, StateAndRef<LinearState>>
get() = currentWallet.let { wallet ->
wallet.states.filterStatesOfType<LinearState>().associateBy { it.state.data.linearId }.mapValues { it.value }
get() = currentVault.let { vault ->
vault.states.filterStatesOfType<LinearState>().associateBy { it.state.data.linearId }.mapValues { it.value }
}
override fun notifyAll(txns: Iterable<WireTransaction>): Wallet {
override fun notifyAll(txns: Iterable<WireTransaction>): Vault {
val ourKeys = services.keyManagementService.keys.keys
// Note how terribly incomplete this all is!
//
// - We don't notify anyone of anything, there are no event listeners.
// - We don't handle or even notice invalidations due to double spends of things in our wallet.
// - We don't handle or even notice invalidations due to double spends of things in our vault.
// - We have no concept of confidence (for txns where there is no definite finality).
// - No notification that keys are used, for the case where we observe a spend of our own states.
// - No ability to create complex spends.
// - No logging or tracking of how the wallet got into this state.
// - No logging or tracking of how the vault got into this state.
// - No persistence.
// - Does tx relevancy calculation and key management need to be interlocked? Probably yes.
//
// ... and many other things .... (Wallet.java in bitcoinj is several thousand lines long)
var netDelta = Wallet.NoUpdate
val changedWallet = mutex.locked {
// Starting from the current wallet, keep applying the transaction updates, calculating a new Wallet each
var netDelta = Vault.NoUpdate
val changedVault = mutex.locked {
// Starting from the current vault, keep applying the transaction updates, calculating a new vault each
// time, until we get to the result (this is perhaps a bit inefficient, but it's functional and easily
// unit tested).
val walletAndNetDelta = txns.fold(Pair(currentWallet, Wallet.NoUpdate)) { walletAndDelta, tx ->
val (wallet, delta) = walletAndDelta.first.update(tx, ourKeys)
val combinedDelta = delta + walletAndDelta.second
Pair(wallet, combinedDelta)
val vaultAndNetDelta = txns.fold(Pair(currentVault, Vault.NoUpdate)) { vaultAndDelta, tx ->
val (vault, delta) = vaultAndDelta.first.update(tx, ourKeys)
val combinedDelta = delta + vaultAndDelta.second
Pair(vault, combinedDelta)
}
wallet = walletAndNetDelta.first
netDelta = walletAndNetDelta.second
return@locked wallet
vault = vaultAndNetDelta.first
netDelta = vaultAndNetDelta.second
return@locked vault
}
if (netDelta != Wallet.NoUpdate) {
if (netDelta != Vault.NoUpdate) {
_updatesPublisher.onNext(netDelta)
}
return changedWallet
return changedVault
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>): Boolean {
return if (state is OwnableState) {
state.owner in ourKeys
} else if (state is LinearState) {
// It's potentially of interest to the wallet
// It's potentially of interest to the vault
state.isRelevant(ourKeys)
} else {
false
}
}
private fun Wallet.update(tx: WireTransaction, ourKeys: Set<PublicKey>): Pair<Wallet, Wallet.Update> {
private fun Vault.update(tx: WireTransaction, ourKeys: Set<PublicKey>): Pair<Vault, Vault.Update> {
val ourNewStates = tx.outputs.
filter { isRelevant(it.data, ourKeys) }.
map { tx.outRef<ContractState>(it.data) }
@ -108,19 +108,19 @@ open class InMemoryWalletService(protected val services: ServiceHub) : Singleton
// Is transaction irrelevant?
if (consumed.isEmpty() && ourNewStates.isEmpty()) {
log.trace { "tx ${tx.id} was irrelevant to this wallet, ignoring" }
return Pair(this, Wallet.NoUpdate)
log.trace { "tx ${tx.id} was irrelevant to this vault, ignoring" }
return Pair(this, Vault.NoUpdate)
}
val change = Wallet.Update(consumed, HashSet(ourNewStates))
val change = Vault.Update(consumed, HashSet(ourNewStates))
// And calculate the new wallet.
// And calculate the new vault.
val newStates = states.filter { it.ref !in consumed } + ourNewStates
log.trace {
"Applied tx ${tx.id.prefixChars()} to the wallet: consumed ${consumed.size} states and added ${newStates.size}"
"Applied tx ${tx.id.prefixChars()} to the vault: consumed ${consumed.size} states and added ${newStates.size}"
}
return Pair(Wallet(newStates), change)
return Pair(Vault(newStates), change)
}
}

View File

@ -2,14 +2,14 @@ package com.r3corda.core.node
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.utilities.DUMMY_NOTARY
import org.junit.Test
import java.security.PublicKey
import kotlin.test.assertEquals
class WalletUpdateTests {
class VaultUpdateTests {
object DummyContract : Contract {
@ -22,7 +22,7 @@ class WalletUpdateTests {
private class DummyState : ContractState {
override val participants: List<PublicKey>
get() = emptyList()
override val contract = WalletUpdateTests.DummyContract
override val contract = VaultUpdateTests.DummyContract
}
private val stateRef0 = StateRef(SecureHash.randomSHA256(), 0)
@ -39,47 +39,47 @@ class WalletUpdateTests {
@Test
fun `nothing plus nothing is nothing`() {
val before = Wallet.NoUpdate
val after = before + Wallet.NoUpdate
val before = Vault.NoUpdate
val after = before + Vault.NoUpdate
assertEquals(before, after)
}
@Test
fun `something plus nothing is something`() {
val before = Wallet.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
val after = before + Wallet.NoUpdate
val before = Vault.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
val after = before + Vault.NoUpdate
assertEquals(before, after)
}
@Test
fun `nothing plus something is something`() {
val before = Wallet.NoUpdate
val after = before + Wallet.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
val expected = Wallet.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
val before = Vault.NoUpdate
val after = before + Vault.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
val expected = Vault.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef2, stateAndRef3))
assertEquals(expected, after)
}
@Test
fun `something plus consume state 0 is something without state 0 output`() {
val before = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Wallet.Update(setOf(stateRef0), setOf())
val expected = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef1))
val before = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update(setOf(stateRef0), setOf())
val expected = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef1))
assertEquals(expected, after)
}
@Test
fun `something plus produce state 4 is something with additional state 4 output`() {
val before = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Wallet.Update(setOf(), setOf(stateAndRef4))
val expected = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1, stateAndRef4))
val before = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update(setOf(), setOf(stateAndRef4))
val expected = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1, stateAndRef4))
assertEquals(expected, after)
}
@Test
fun `something plus consume states 0 and 1, and produce state 4, is something without state 0 and 1 outputs and only state 4 output`() {
val before = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Wallet.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef4))
val expected = Wallet.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef4))
val before = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef0, stateAndRef1))
val after = before + Vault.Update(setOf(stateRef0, stateRef1), setOf(stateAndRef4))
val expected = Vault.Update(setOf(stateRef2, stateRef3), setOf(stateAndRef4))
assertEquals(expected, after)
}
}

View File

@ -13,6 +13,8 @@ API changes:
location.
* ``AbstractStateReplacementProtocol.verifyProposal`` has changed its prototype in a minor way.
* The ``UntrustworthyData<T>.validate`` method has been renamed to ``unwrap`` - the old name is now deprecated.
* The wallet, wallet service, etc. are now vault, vault service, etc. These better reflect the intent that they
are a generic secure data store, rather than something which holds cash.
Milestone 3
-----------

View File

@ -30,10 +30,10 @@ class APIServerImpl(val node: AbstractNode) : APIServer {
// something we can't later implement against a persistent store (i.e. need to pick / build a query engine)
if (query is StatesQuery.Selection) {
if (query.criteria is StatesQuery.Criteria.AllDeals) {
val states = node.services.walletService.linearHeads
val states = node.services.vaultService.linearHeads
return states.values.map { it.ref }
} else if (query.criteria is StatesQuery.Criteria.Deal) {
val states = node.services.walletService.linearHeadsOfType<DealState>().filterValues {
val states = node.services.vaultService.linearHeadsOfType<DealState>().filterValues {
it.state.data.ref == query.criteria.ref
}
return states.values.map { it.ref }
@ -43,7 +43,7 @@ class APIServerImpl(val node: AbstractNode) : APIServer {
}
override fun fetchStates(states: List<StateRef>): Map<StateRef, TransactionState<ContractState>?> {
return node.services.walletService.statesForRefs(states)
return node.services.vaultService.statesForRefs(states)
}
override fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?> {

View File

@ -43,8 +43,8 @@ import com.r3corda.node.services.statemachine.StateMachineManager
import com.r3corda.node.services.transactions.NotaryService
import com.r3corda.node.services.transactions.SimpleNotaryService
import com.r3corda.node.services.transactions.ValidatingNotaryService
import com.r3corda.node.services.wallet.CashBalanceAsMetricsObserver
import com.r3corda.node.services.wallet.NodeWalletService
import com.r3corda.node.services.vault.CashBalanceAsMetricsObserver
import com.r3corda.node.services.vault.NodeVaultService
import com.r3corda.node.utilities.*
import org.slf4j.Logger
import java.nio.file.FileAlreadyExistsException
@ -94,7 +94,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
override val networkService: MessagingServiceInternal get() = net
override val networkMapCache: NetworkMapCache get() = netMapCache
override val storageService: TxWritableStorageService get() = storage
override val walletService: WalletService get() = wallet
override val vaultService: VaultService get() = vault
override val keyManagementService: KeyManagementService get() = keyManagement
override val identityService: IdentityService get() = identity
override val schedulerService: SchedulerService get() = scheduler
@ -121,7 +121,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
lateinit var storage: TxWritableStorageService
lateinit var checkpointStorage: CheckpointStorage
lateinit var smm: StateMachineManager
lateinit var wallet: WalletService
lateinit var vault: VaultService
lateinit var keyManagement: KeyManagementService
var inNodeNetworkMapService: NetworkMapService? = null
var inNodeWalletMonitorService: WalletMonitorService? = null
@ -167,7 +167,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
checkpointStorage = storageServices.second
netMapCache = InMemoryNetworkMapCache()
net = makeMessagingService()
wallet = makeWalletService()
vault = makeVaultService()
identity = makeIdentityService()
@ -180,7 +180,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
protocolLogicFactory = initialiseProtocolLogicFactory()
val tokenizableServices = mutableListOf(storage, net, wallet, keyManagement, identity, platformClock, scheduler)
val tokenizableServices = mutableListOf(storage, net, vault, keyManagement, identity, platformClock, scheduler)
customServices.clear()
customServices.addAll(buildPluginServices(tokenizableServices))
@ -211,7 +211,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
// TODO: this model might change but for now it provides some de-coupling
// Add SMM observers
ANSIProgressObserver(smm)
// Add wallet observers
// Add vault observers
CashBalanceAsMetricsObserver(services)
ScheduledActivityObserver(services)
}
@ -372,7 +372,7 @@ abstract class AbstractNode(val dir: Path, val configuration: NodeConfiguration,
}
// TODO: sort out ordering of open & protected modifiers of functions in this class.
protected open fun makeWalletService(): WalletService = NodeWalletService(services)
protected open fun makeVaultService(): VaultService = NodeVaultService(services)
protected open fun makeWalletMonitorService(): WalletMonitorService = WalletMonitorService(services, smm)

View File

@ -39,14 +39,14 @@ abstract class ServiceHubInternal : ServiceHub {
/**
* Given a list of [SignedTransaction]s, writes them to the given storage for validated transactions and then
* sends them to the wallet for further processing. This is intended for implementations to call from
* sends them to the vault for further processing. This is intended for implementations to call from
* [recordTransactions].
*
* @param txs The transactions to record.
*/
internal fun recordTransactionsInternal(writableStorageService: TxWritableStorageService, txs: Iterable<SignedTransaction>) {
txs.forEach { writableStorageService.validatedTransactions.addTransaction(it) }
walletService.notifyAll(txs.map { it.tx })
vaultService.notifyAll(txs.map { it.tx })
}
/**

View File

@ -20,7 +20,7 @@ import javax.annotation.concurrent.ThreadSafe
/**
* A first pass of a simple [SchedulerService] that works with [MutableClock]s for testing, demonstrations and simulations
* that also encompasses the [Wallet] observer for processing transactions.
* that also encompasses the [Vault] observer for processing transactions.
*
* This will observe transactions as they are stored and schedule and unschedule activities based on the States consumed
* or produced.
@ -50,7 +50,7 @@ class NodeSchedulerService(private val services: ServiceHubInternal,
// to somewhere.
private class InnerState {
// TODO: This has no persistence, and we don't consider initialising from non-empty map if we add persistence.
// If we were to rebuild the wallet at start up by replaying transactions and re-calculating, then
// If we were to rebuild the vault at start up by replaying transactions and re-calculating, then
// persistence here would be unnecessary.
var scheduledStates = HashMap<StateRef, ScheduledStateRef>()
var earliestState: ScheduledStateRef? = null

View File

@ -8,21 +8,21 @@ import com.r3corda.core.protocols.ProtocolLogicRefFactory
import com.r3corda.node.services.api.ServiceHubInternal
/**
* This observes the wallet and schedules and unschedules activities appropriately based on state production and
* This observes the vault and schedules and unschedules activities appropriately based on state production and
* consumption.
*/
class ScheduledActivityObserver(val services: ServiceHubInternal) {
init {
// TODO: Need to consider failure scenarios. This needs to run if the TX is successfully recorded
services.walletService.updates.subscribe { update ->
services.vaultService.updates.subscribe { update ->
update.consumed.forEach { services.schedulerService.unscheduleStateActivity(it) }
update.produced.forEach { scheduleStateActivity(it, services.protocolLogicRefFactory) }
}
// In the short term, to get restart-able IRS demo, re-initialise from wallet state
// In the short term, to get restart-able IRS demo, re-initialise from vault state
// TODO: there's a race condition here. We need to move persistence into the scheduler but that is a bigger
// change so I want to revisit as a distinct branch/PR.
for (state in services.walletService.currentWallet.statesOfType<SchedulableState>()) {
for (state in services.vaultService.currentVault.statesOfType<SchedulableState>()) {
scheduleStateActivity(state, services.protocolLogicRefFactory)
}
}

View File

@ -8,7 +8,7 @@ import com.r3corda.core.crypto.Party
import com.r3corda.core.crypto.toStringShort
import com.r3corda.core.messaging.MessageRecipients
import com.r3corda.core.node.services.DEFAULT_SESSION_ID
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.protocols.ProtocolLogic
import com.r3corda.core.serialization.serialize
import com.r3corda.core.transactions.LedgerTransaction
@ -60,7 +60,7 @@ class WalletMonitorService(services: ServiceHubInternal, val smm: StateMachineMa
// Notify listeners on state changes
services.storageService.validatedTransactions.updates.subscribe { tx -> notifyTransaction(tx.tx.toLedgerTransaction(services)) }
services.walletService.updates.subscribe { update -> notifyWalletUpdate(update) }
services.vaultService.updates.subscribe { update -> notifyVaultUpdate(update) }
smm.changes.subscribe { change ->
val fiberId: Long = change.third
val logic: ProtocolLogic<*> = change.first
@ -81,7 +81,7 @@ class WalletMonitorService(services: ServiceHubInternal, val smm: StateMachineMa
}
@VisibleForTesting
internal fun notifyWalletUpdate(update: Wallet.Update)
internal fun notifyVaultUpdate(update: Vault.Update)
= notifyEvent(ServiceToClientEvent.OutputState(Instant.now(), update.consumed, update.produced))
@VisibleForTesting
@ -135,7 +135,7 @@ class WalletMonitorService(services: ServiceHubInternal, val smm: StateMachineMa
fun processRegisterRequest(req: RegisterRequest) {
try {
listeners.add(RegisteredListener(req.replyToRecipient, req.sessionID))
val stateMessage = StateSnapshotMessage(services.walletService.currentWallet.states.toList(),
val stateMessage = StateSnapshotMessage(services.vaultService.currentVault.states.toList(),
smm.allStateMachines.map { it.javaClass.name })
net.send(net.createMessage(STATE_TOPIC, DEFAULT_SESSION_ID, stateMessage.serialize().bits), req.replyToRecipient)
@ -158,7 +158,7 @@ class WalletMonitorService(services: ServiceHubInternal, val smm: StateMachineMa
try {
Cash().generateSpend(builder, req.amount.withoutIssuer(), req.recipient.owningKey,
// TODO: Move cash state filtering by issuer down to the contract itself
services.walletService.currentWallet.statesOfType<Cash.State>().filter { it.state.data.amount.token == req.amount.token },
services.vaultService.currentVault.statesOfType<Cash.State>().filter { it.state.data.amount.token == req.amount.token },
setOf(req.amount.token.issuer.party))
.forEach {
val key = services.keyManagementService.keys[it] ?: throw IllegalStateException("Could not find signing key for ${it.toStringShort()}")
@ -182,11 +182,11 @@ class WalletMonitorService(services: ServiceHubInternal, val smm: StateMachineMa
try {
val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef)
Cash().generateExit(builder, req.amount.issuedBy(issuer),
services.walletService.currentWallet.statesOfType<Cash.State>().filter { it.state.data.owner == issuer.party.owningKey })
services.vaultService.currentVault.statesOfType<Cash.State>().filter { it.state.data.owner == issuer.party.owningKey })
builder.signWith(services.storageService.myLegalIdentityKey)
// Work out who the owners of the burnt states were
val inputStatesNullable = services.walletService.statesForRefs(builder.inputStates())
val inputStatesNullable = services.vaultService.statesForRefs(builder.inputStates())
val inputStates = inputStatesNullable.values.filterNotNull().map { it.data }
if (inputStatesNullable.size != inputStates.size) {
val unresolvedStateRefs = inputStatesNullable.filter { it.value == null }.map { it.key }

View File

@ -1,19 +1,19 @@
package com.r3corda.node.services.wallet
package com.r3corda.node.services.vault
import com.codahale.metrics.Gauge
import com.r3corda.contracts.asset.cashBalances
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.node.services.api.ServiceHubInternal
import java.util.*
/**
* This class observes the wallet and reflect current cash balances as exposed metrics in the monitoring service.
* This class observes the vault and reflect current cash balances as exposed metrics in the monitoring service.
*/
class CashBalanceAsMetricsObserver(val serviceHubInternal: ServiceHubInternal) {
init {
// TODO: Need to consider failure scenarios. This needs to run if the TX is successfully recorded
serviceHubInternal.walletService.updates.subscribe { update ->
exportCashBalancesViaMetrics(serviceHubInternal.walletService.currentWallet)
serviceHubInternal.vaultService.updates.subscribe { update ->
exportCashBalancesViaMetrics(serviceHubInternal.vaultService.currentVault)
}
}
@ -24,16 +24,16 @@ class CashBalanceAsMetricsObserver(val serviceHubInternal: ServiceHubInternal) {
private val balanceMetrics = HashMap<Currency, BalanceMetric>()
private fun exportCashBalancesViaMetrics(wallet: Wallet) {
private fun exportCashBalancesViaMetrics(vault: Vault) {
// This is just for demo purposes. We probably shouldn't expose balances via JMX in a real node as that might
// be commercially sensitive info that the sysadmins aren't even meant to know.
//
// Note: exported as pennies.
val m = serviceHubInternal.monitoringService.metrics
for ((key, value) in wallet.cashBalances) {
for ((key, value) in vault.cashBalances) {
val metric = balanceMetrics.getOrPut(key) {
val newMetric = BalanceMetric()
m.register("WalletBalances.${key}Pennies", newMetric)
m.register("VaultBalances.${key}Pennies", newMetric)
newMetric
}
metric.pennies = value.quantity

View File

@ -1,11 +1,11 @@
package com.r3corda.node.services.wallet
package com.r3corda.node.services.vault
import com.google.common.collect.Sets
import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.WalletService
import com.r3corda.core.node.services.Vault
import com.r3corda.core.node.services.VaultService
import com.r3corda.core.serialization.SingletonSerializeAsToken
import com.r3corda.core.transactions.WireTransaction
import com.r3corda.core.utilities.loggerFor
@ -21,8 +21,8 @@ import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock
/**
* Currently, the node wallet service is a very simple RDBMS backed implementation. It will change significantly when
* we add further functionality as the design for the wallet and wallet service matures.
* Currently, the node vault service is a very simple RDBMS backed implementation. It will change significantly when
* we add further functionality as the design for the vault and vault service matures.
*
* This class needs database transactions to be in-flight during method calls and init, and will throw exceptions if
* this is not the case.
@ -31,10 +31,10 @@ import kotlin.concurrent.withLock
* TODO: keep an audit trail with time stamps of previously unconsumed states "as of" a particular point in time.
* TODO: have transaction storage do some caching.
*/
class NodeWalletService(private val services: ServiceHub) : SingletonSerializeAsToken(), WalletService {
class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsToken(), VaultService {
private companion object {
val log = loggerFor<NodeWalletService>()
val log = loggerFor<NodeVaultService>()
}
private object StatesSetTable : JDBCHashedTable("vault_unconsumed_states") {
@ -53,11 +53,11 @@ class NodeWalletService(private val services: ServiceHub) : SingletonSerializeAs
protected val mutex = ReentrantLock()
override val currentWallet: Wallet get() = mutex.withLock { Wallet(allUnconsumedStates()) }
override val currentVault: Vault get() = mutex.withLock { Vault(allUnconsumedStates()) }
private val _updatesPublisher = PublishSubject.create<Wallet.Update>()
private val _updatesPublisher = PublishSubject.create<Vault.Update>()
override val updates: Observable<Wallet.Update>
override val updates: Observable<Vault.Update>
get() = _updatesPublisher
/**
@ -66,21 +66,21 @@ class NodeWalletService(private val services: ServiceHub) : SingletonSerializeAs
* TODO: Represent this using an actual JDBCHashMap or look at vault design further.
*/
override val linearHeads: Map<UniqueIdentifier, StateAndRef<LinearState>>
get() = currentWallet.states.filterStatesOfType<LinearState>().associateBy { it.state.data.linearId }.mapValues { it.value }
get() = currentVault.states.filterStatesOfType<LinearState>().associateBy { it.state.data.linearId }.mapValues { it.value }
override fun notifyAll(txns: Iterable<WireTransaction>): Wallet {
override fun notifyAll(txns: Iterable<WireTransaction>): Vault {
val ourKeys = services.keyManagementService.keys.keys
val netDelta = txns.fold(Wallet.NoUpdate) { netDelta, txn -> netDelta + makeUpdate(txn, netDelta, ourKeys) }
if (netDelta != Wallet.NoUpdate) {
val netDelta = txns.fold(Vault.NoUpdate) { netDelta, txn -> netDelta + makeUpdate(txn, netDelta, ourKeys) }
if (netDelta != Vault.NoUpdate) {
mutex.withLock {
recordUpdate(netDelta)
}
_updatesPublisher.onNext(netDelta)
}
return currentWallet
return currentVault
}
private fun makeUpdate(tx: WireTransaction, netDelta: Wallet.Update, ourKeys: Set<PublicKey>): Wallet.Update {
private fun makeUpdate(tx: WireTransaction, netDelta: Vault.Update, ourKeys: Set<PublicKey>): Vault.Update {
val ourNewStates = tx.outputs.
filter { isRelevant(it.data, ourKeys) }.
map { tx.outRef<ContractState>(it.data) }
@ -95,26 +95,26 @@ class NodeWalletService(private val services: ServiceHub) : SingletonSerializeAs
// Is transaction irrelevant?
if (consumed.isEmpty() && ourNewStates.isEmpty()) {
log.trace { "tx ${tx.id} was irrelevant to this wallet, ignoring" }
return Wallet.NoUpdate
log.trace { "tx ${tx.id} was irrelevant to this vault, ignoring" }
return Vault.NoUpdate
}
return Wallet.Update(consumed, ourNewStates.toHashSet())
return Vault.Update(consumed, ourNewStates.toHashSet())
}
private fun isRelevant(state: ContractState, ourKeys: Set<PublicKey>): Boolean {
return if (state is OwnableState) {
state.owner in ourKeys
} else if (state is LinearState) {
// It's potentially of interest to the wallet
// It's potentially of interest to the vault
state.isRelevant(ourKeys)
} else {
false
}
}
private fun recordUpdate(update: Wallet.Update): Wallet.Update {
if (update != Wallet.NoUpdate) {
private fun recordUpdate(update: Vault.Update): Vault.Update {
if (update != Vault.NoUpdate) {
val producedStateRefs = update.produced.map { it.ref }
val consumedStateRefs = update.consumed
log.trace { "Removing $consumedStateRefs consumed contract states and adding $producedStateRefs produced contract states to the database." }

View File

@ -11,7 +11,7 @@ import com.r3corda.core.messaging.SingleMessageRecipient
import com.r3corda.core.node.ServiceHub
import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.node.services.TransactionStorage
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.transactions.WireTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
@ -370,7 +370,7 @@ class TwoPartyTradeProtocolTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean,
owner: PublicKey = BOB_PUBKEY): Pair<Wallet, List<WireTransaction>> {
owner: PublicKey = BOB_PUBKEY): Pair<Vault, List<WireTransaction>> {
val issuer = DUMMY_CASH_ISSUER
// Bob (Buyer) has some cash he got from the Bank of Elbonia, Alice (Seller) has some commercial paper she
// wants to sell to Bob.
@ -407,15 +407,15 @@ class TwoPartyTradeProtocolTests {
this.verifies()
}
val wallet = Wallet(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef()))
return Pair(wallet, listOf(eb1, bc1, bc2))
val vault = Vault(listOf("bob cash 1".outputStateAndRef(), "bob cash 2".outputStateAndRef()))
return Pair(vault, listOf(eb1, bc1, bc2))
}
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForSeller(
withError: Boolean,
owner: PublicKey,
amount: Amount<Issued<Currency>>,
attachmentID: SecureHash?): Pair<Wallet, List<WireTransaction>> {
attachmentID: SecureHash?): Pair<Vault, List<WireTransaction>> {
val ap = transaction {
output("alice's paper") {
CommercialPaper.State(MEGA_CORP.ref(1, 2, 3), owner, amount, TEST_TX_TIME + 7.days)
@ -432,8 +432,8 @@ class TwoPartyTradeProtocolTests {
}
}
val wallet = Wallet(listOf("alice's paper".outputStateAndRef()))
return Pair(wallet, listOf(ap))
val vault = Vault(listOf("alice's paper".outputStateAndRef()))
return Pair(vault, listOf(ap))
}
class RecordingTransactionStorage(val delegate: TransactionStorage) : TransactionStorage {

View File

@ -14,14 +14,14 @@ import com.r3corda.testing.node.MockNetworkMapCache
import com.r3corda.node.services.network.NetworkMapService
import com.r3corda.node.services.persistence.DataVending
import com.r3corda.node.services.statemachine.StateMachineManager
import com.r3corda.core.testing.InMemoryWalletService
import com.r3corda.core.testing.InMemoryVaultService
import com.r3corda.testing.node.MockStorageService
import com.r3corda.testing.MOCK_IDENTITY_SERVICE
import java.time.Clock
@Suppress("LeakingThis")
open class MockServiceHubInternal(
customWallet: WalletService? = null,
customVault: VaultService? = null,
val keyManagement: KeyManagementService? = null,
val net: MessagingServiceInternal? = null,
val identity: IdentityService? = MOCK_IDENTITY_SERVICE,
@ -32,7 +32,7 @@ open class MockServiceHubInternal(
val overrideClock: Clock? = NodeClock(),
val protocolFactory: ProtocolLogicRefFactory? = ProtocolLogicRefFactory()
) : ServiceHubInternal() {
override val walletService: WalletService = customWallet ?: InMemoryWalletService(this)
override val vaultService: VaultService = customVault ?: InMemoryVaultService(this)
override val keyManagementService: KeyManagementService
get() = keyManagement ?: throw UnsupportedOperationException()
override val identityService: IdentityService

View File

@ -17,7 +17,7 @@ import com.r3corda.node.services.events.NodeSchedulerService
import com.r3corda.testing.node.InMemoryMessagingNetwork
import com.r3corda.node.services.persistence.PerFileCheckpointStorage
import com.r3corda.node.services.statemachine.StateMachineManager
import com.r3corda.node.services.wallet.NodeWalletService
import com.r3corda.node.services.vault.NodeVaultService
import com.r3corda.node.utilities.AddOrRemove
import com.r3corda.node.utilities.AffinityExecutor
import com.r3corda.node.utilities.configureDatabase

View File

@ -3,11 +3,11 @@ package com.r3corda.node.services
import com.r3corda.contracts.testing.fillWithSomeTestCash
import com.r3corda.core.contracts.DOLLARS
import com.r3corda.core.node.services.TxWritableStorageService
import com.r3corda.core.node.services.WalletService
import com.r3corda.core.node.services.VaultService
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.LogHelper
import com.r3corda.node.services.wallet.NodeWalletService
import com.r3corda.node.services.vault.NodeVaultService
import com.r3corda.node.utilities.configureDatabase
import com.r3corda.node.utilities.databaseTransaction
import com.r3corda.testing.node.MockServices
@ -19,42 +19,42 @@ import org.junit.Test
import java.io.Closeable
import java.util.*
class NodeWalletServiceTest {
class NodeVaultServiceTest {
lateinit var dataSource: Closeable
@Before
fun setUp() {
LogHelper.setLevel(NodeWalletService::class)
LogHelper.setLevel(NodeVaultService::class)
dataSource = configureDatabase(makeTestDataSourceProperties()).first
}
@After
fun tearDown() {
dataSource.close()
LogHelper.reset(NodeWalletService::class)
LogHelper.reset(NodeVaultService::class)
}
@Test
fun `states not local to instance`() {
databaseTransaction {
val services1 = object : MockServices() {
override val walletService: WalletService = NodeWalletService(this)
override val vaultService: VaultService = NodeVaultService(this)
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
for (stx in txs) {
storageService.validatedTransactions.addTransaction(stx)
walletService.notify(stx.tx)
vaultService.notify(stx.tx)
}
}
}
services1.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L))
val w1 = services1.walletService.currentWallet
val w1 = services1.vaultService.currentVault
assertThat(w1.states).hasSize(3)
val originalStorage = services1.storageService
val services2 = object : MockServices() {
override val walletService: WalletService = NodeWalletService(this)
override val vaultService: VaultService = NodeVaultService(this)
// We need to be able to find the same transactions as before, too.
override val storageService: TxWritableStorageService get() = originalStorage
@ -62,12 +62,12 @@ class NodeWalletServiceTest {
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
for (stx in txs) {
storageService.validatedTransactions.addTransaction(stx)
walletService.notify(stx.tx)
vaultService.notify(stx.tx)
}
}
}
val w2 = services2.walletService.currentWallet
val w2 = services2.vaultService.currentVault
assertThat(w2.states).hasSize(3)
}
}

View File

@ -5,12 +5,12 @@ import com.r3corda.contracts.asset.DUMMY_CASH_ISSUER
import com.r3corda.contracts.asset.cashBalances
import com.r3corda.contracts.testing.fillWithSomeTestCash
import com.r3corda.core.contracts.*
import com.r3corda.core.node.services.WalletService
import com.r3corda.core.node.services.VaultService
import com.r3corda.core.transactions.SignedTransaction
import com.r3corda.core.utilities.DUMMY_NOTARY
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
import com.r3corda.core.utilities.LogHelper
import com.r3corda.node.services.wallet.NodeWalletService
import com.r3corda.node.services.vault.NodeVaultService
import com.r3corda.node.utilities.configureDatabase
import com.r3corda.node.utilities.databaseTransaction
import com.r3corda.testing.*
@ -27,25 +27,25 @@ import kotlin.test.assertNull
// TODO: Move this to the cash contract tests once mock services are further split up.
class WalletWithCashTest {
class VaultWithCashTest {
lateinit var services: MockServices
val wallet: WalletService get() = services.walletService
val vault: VaultService get() = services.vaultService
lateinit var dataSource: Closeable
@Before
fun setUp() {
LogHelper.setLevel(NodeWalletService::class)
LogHelper.setLevel(NodeVaultService::class)
dataSource = configureDatabase(makeTestDataSourceProperties()).first
databaseTransaction {
services = object : MockServices() {
override val walletService: WalletService = NodeWalletService(this)
override val vaultService: VaultService = NodeVaultService(this)
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
for (stx in txs) {
storageService.validatedTransactions.addTransaction(stx)
}
// Refactored to use notifyAll() as we have no other unit test for that method with multiple transactions.
walletService.notifyAll(txs.map { it.tx })
vaultService.notifyAll(txs.map { it.tx })
}
}
}
@ -53,7 +53,7 @@ class WalletWithCashTest {
@After
fun tearDown() {
LogHelper.reset(NodeWalletService::class)
LogHelper.reset(NodeVaultService::class)
dataSource.close()
}
@ -63,7 +63,7 @@ class WalletWithCashTest {
// Fix the PRNG so that we get the same splits every time.
services.fillWithSomeTestCash(100.DOLLARS, DUMMY_NOTARY, 3, 3, Random(0L))
val w = wallet.currentWallet
val w = vault.currentVault
assertEquals(3, w.states.toList().size)
val state = w.states.toList()[0].state.data as Cash.State
@ -100,14 +100,14 @@ class WalletWithCashTest {
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
assertNull(wallet.currentWallet.cashBalances[USD])
assertNull(vault.currentVault.cashBalances[USD])
services.recordTransactions(usefulTX)
assertEquals(100.DOLLARS, wallet.currentWallet.cashBalances[USD])
assertEquals(100.DOLLARS, vault.currentVault.cashBalances[USD])
services.recordTransactions(irrelevantTX)
assertEquals(100.DOLLARS, wallet.currentWallet.cashBalances[USD])
assertEquals(100.DOLLARS, vault.currentVault.cashBalances[USD])
services.recordTransactions(spendTX)
assertEquals(20.DOLLARS, wallet.currentWallet.cashBalances[USD])
assertEquals(20.DOLLARS, vault.currentVault.cashBalances[USD])
// TODO: Flesh out these tests as needed.
}
@ -151,7 +151,7 @@ class WalletWithCashTest {
dummyIssue.toLedgerTransaction(services).verify()
services.recordTransactions(dummyIssue)
assertEquals(1, wallet.currentWallet.states.toList().size)
assertEquals(1, vault.currentVault.states.toList().size)
// Move the same state
val dummyMove = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
@ -163,7 +163,7 @@ class WalletWithCashTest {
dummyIssue.toLedgerTransaction(services).verify()
services.recordTransactions(dummyMove)
assertEquals(1, wallet.currentWallet.states.toList().size)
assertEquals(1, vault.currentVault.states.toList().size)
}
}
}

View File

@ -6,7 +6,7 @@ import com.r3corda.core.contracts.*
import com.r3corda.core.crypto.SecureHash
import com.r3corda.core.crypto.newSecureRandom
import com.r3corda.core.node.services.DEFAULT_SESSION_ID
import com.r3corda.core.node.services.Wallet
import com.r3corda.core.node.services.Vault
import com.r3corda.core.random63BitValue
import com.r3corda.core.serialization.OpaqueBytes
import com.r3corda.core.serialization.deserialize
@ -77,8 +77,8 @@ class WalletMonitorServiceTests {
val (monitorServiceNode, registerNode) = network.createTwoNodes()
val sessionID = authenticate(monitorServiceNode, registerNode)
var receivePsm = receiveWalletUpdate(registerNode, sessionID)
var expected = Wallet.Update(emptySet(), emptySet())
monitorServiceNode.inNodeWalletMonitorService!!.notifyWalletUpdate(expected)
var expected = Vault.Update(emptySet(), emptySet())
monitorServiceNode.inNodeWalletMonitorService!!.notifyVaultUpdate(expected)
network.runNetwork()
var actual = receivePsm.get(1, TimeUnit.SECONDS)
assertEquals(expected.consumed, actual.consumed)
@ -89,8 +89,8 @@ class WalletMonitorServiceTests {
val consumed = setOf(StateRef(SecureHash.randomSHA256(), 0))
val producedState = TransactionState(DummyContract.SingleOwnerState(newSecureRandom().nextInt(), DUMMY_PUBKEY_1), DUMMY_NOTARY)
val produced = setOf(StateAndRef(producedState, StateRef(SecureHash.randomSHA256(), 0)))
expected = Wallet.Update(consumed, produced)
monitorServiceNode.inNodeWalletMonitorService!!.notifyWalletUpdate(expected)
expected = Vault.Update(consumed, produced)
monitorServiceNode.inNodeWalletMonitorService!!.notifyVaultUpdate(expected)
network.runNetwork()
actual = receivePsm.get(1, TimeUnit.SECONDS)
assertEquals(expected.produced, actual.produced)
@ -110,7 +110,7 @@ class WalletMonitorServiceTests {
}
// Check the monitoring service wallet is empty
assertFalse(monitorServiceNode.services.walletService.currentWallet.states.iterator().hasNext())
assertFalse(monitorServiceNode.services.vaultService.currentVault.states.iterator().hasNext())
// Tell the monitoring service node to issue some cash
val recipient = monitorServiceNode.services.storageService.myLegalIdentity

View File

@ -25,8 +25,8 @@ class DataVendingServiceTests {
@Test
fun `notify of transaction`() {
val (walletServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = walletServiceNode.services.storageService.myLegalIdentityKey.public
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public
val deposit = registerNode.services.storageService.myLegalIdentity.ref(1)
network.runNetwork()
@ -37,13 +37,13 @@ class DataVendingServiceTests {
// Complete the cash transaction, and then manually relay it
ptx.signWith(registerNode.services.storageService.myLegalIdentityKey)
val tx = ptx.toSignedTransaction()
assertEquals(0, walletServiceNode.services.walletService.currentWallet.states.toList().size)
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
DataVending.Service.notify(registerNode.net, registerNode.services.storageService.myLegalIdentity,
walletServiceNode.info, tx)
vaultServiceNode.info, tx)
network.runNetwork()
// Check the transaction is in the receiving node
val actual = walletServiceNode.services.walletService.currentWallet.states.singleOrNull()
val actual = vaultServiceNode.services.vaultService.currentVault.states.singleOrNull()
val expected = tx.tx.outRef<Cash.State>(0)
assertEquals(expected, actual)
@ -54,8 +54,8 @@ class DataVendingServiceTests {
*/
@Test
fun `notify failure`() {
val (walletServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = walletServiceNode.services.storageService.myLegalIdentityKey.public
val (vaultServiceNode, registerNode) = network.createTwoNodes()
val beneficiary = vaultServiceNode.services.storageService.myLegalIdentityKey.public
val deposit = MEGA_CORP.ref(1)
network.runNetwork()
@ -66,12 +66,12 @@ class DataVendingServiceTests {
// The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid
ptx.signWith(registerNode.services.storageService.myLegalIdentityKey)
val tx = ptx.toSignedTransaction(false)
assertEquals(0, walletServiceNode.services.walletService.currentWallet.states.toList().size)
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
DataVending.Service.notify(registerNode.net, registerNode.services.storageService.myLegalIdentity,
walletServiceNode.info, tx)
vaultServiceNode.info, tx)
network.runNetwork()
// Check the transaction is not in the receiving node
assertEquals(0, walletServiceNode.services.walletService.currentWallet.states.toList().size)
assertEquals(0, vaultServiceNode.services.vaultService.currentVault.states.toList().size)
}
}

View File

@ -260,7 +260,7 @@ private class TraderDemoProtocolBuyer(val otherSide: Party,
}
private fun logBalance() {
val balances = serviceHub.walletService.currentWallet.cashBalances.entries.map { "${it.key.currencyCode} ${it.value}" }
val balances = serviceHub.vaultService.currentVault.cashBalances.entries.map { "${it.key.currencyCode} ${it.value}" }
logger.info("Remaining balance: ${balances.joinToString()}")
}

View File

@ -48,7 +48,7 @@ class InterestRateSwapAPI(val services: ServiceHub) {
private fun generateDealLink(deal: InterestRateSwap.State) = "/api/irs/deals/" + deal.common.tradeID
private fun getDealByRef(ref: String): InterestRateSwap.State? {
val states = services.walletService.linearHeadsOfType<InterestRateSwap.State>().filterValues { it.state.data.ref == ref }
val states = services.vaultService.linearHeadsOfType<InterestRateSwap.State>().filterValues { it.state.data.ref == ref }
return if (states.isEmpty()) null else {
val deals = states.values.map { it.state.data }
return if (deals.isEmpty()) null else deals[0]
@ -56,7 +56,7 @@ class InterestRateSwapAPI(val services: ServiceHub) {
}
private fun getAllDeals(): Array<InterestRateSwap.State> {
val states = services.walletService.linearHeadsOfType<InterestRateSwap.State>()
val states = services.vaultService.linearHeadsOfType<InterestRateSwap.State>()
val swaps = states.values.map { it.state.data }.toTypedArray()
return swaps
}

View File

@ -79,7 +79,7 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
val node1: SimulatedNode = banks[i]
val node2: SimulatedNode = banks[j]
val swaps: Map<UniqueIdentifier, StateAndRef<InterestRateSwap.State>> = node1.services.walletService.linearHeadsOfType<com.r3corda.contracts.InterestRateSwap.State>()
val swaps: Map<UniqueIdentifier, StateAndRef<InterestRateSwap.State>> = node1.services.vaultService.linearHeadsOfType<com.r3corda.contracts.InterestRateSwap.State>()
val theDealRef: StateAndRef<InterestRateSwap.State> = swaps.values.single()
// Do we have any more days left in this deal's lifetime? If not, return.
@ -89,8 +89,8 @@ class IRSSimulation(networkSendManuallyPumped: Boolean, runAsync: Boolean, laten
val retFuture = SettableFuture.create<Unit>()
// Complete the future when the state has been consumed on both nodes
val futA = node1.services.walletService.whenConsumed(theDealRef.ref)
val futB = node2.services.walletService.whenConsumed(theDealRef.ref)
val futA = node1.services.vaultService.whenConsumed(theDealRef.ref)
val futB = node2.services.vaultService.whenConsumed(theDealRef.ref)
Futures.allAsList(futA, futB) success {
retFuture.set(null)
} failure { throwable ->

View File

@ -13,9 +13,9 @@ import com.r3corda.core.messaging.send
import com.r3corda.core.node.PhysicalLocation
import com.r3corda.core.node.services.KeyManagementService
import com.r3corda.core.node.services.ServiceType
import com.r3corda.core.node.services.WalletService
import com.r3corda.core.node.services.VaultService
import com.r3corda.core.serialization.deserialize
import com.r3corda.core.testing.InMemoryWalletService
import com.r3corda.core.testing.InMemoryVaultService
import com.r3corda.core.utilities.DUMMY_NOTARY_KEY
import com.r3corda.core.utilities.loggerFor
import com.r3corda.node.services.config.NodeConfiguration
@ -91,7 +91,7 @@ class MockNetwork(private val networkSendManuallyPumped: Boolean = false,
override fun makeIdentityService() = MockIdentityService(mockNet.identities)
override fun makeWalletService(): WalletService = InMemoryWalletService(services)
override fun makeVaultService(): VaultService = InMemoryVaultService(services)
override fun makeKeyManagementService(): KeyManagementService = E2ETestKeyManagementService(setOf(storage.myLegalIdentityKey))

View File

@ -51,7 +51,7 @@ open class MockServices(val key: KeyPair = generateKeyPair()) : ServiceHub {
override val identityService: MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
override val keyManagementService: MockKeyManagementService = MockKeyManagementService(key)
override val walletService: WalletService get() = throw UnsupportedOperationException()
override val vaultService: VaultService get() = throw UnsupportedOperationException()
override val networkService: MessagingService get() = throw UnsupportedOperationException()
override val networkMapCache: NetworkMapCache get() = throw UnsupportedOperationException()
override val clock: Clock get() = throw UnsupportedOperationException()