mirror of
https://github.com/corda/corda.git
synced 2025-01-31 08:25:50 +00:00
Merged in colljos-vault-code-clean-up-refactor (pull request #435)
Colljos vault code clean up refactor
This commit is contained in:
commit
6deaf2c12c
@ -32,7 +32,7 @@ import java.util.*
|
||||
import kotlin.test.*
|
||||
|
||||
class CashTests {
|
||||
val defaultRef = OpaqueBytes(ByteArray(1, {1}))
|
||||
val defaultRef = OpaqueBytes(ByteArray(1, { 1 }))
|
||||
val defaultIssuer = MEGA_CORP.ref(defaultRef)
|
||||
val inState = Cash.State(
|
||||
amount = 1000.DOLLARS `issued by` defaultIssuer,
|
||||
@ -85,12 +85,6 @@ class CashTests {
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
fun tearDown() {
|
||||
LogHelper.reset(NodeVaultService::class)
|
||||
dataSource.close()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun trivial() {
|
||||
transaction {
|
||||
@ -264,7 +258,7 @@ class CashTests {
|
||||
// Include the previously issued cash in a new issuance command
|
||||
ptx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
ptx.addInputState(tx.tx.outRef<Cash.State>(0))
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY)
|
||||
Cash().generateIssue(ptx, 100.DOLLARS `issued by` MINI_CORP.ref(12, 34), owner = MINI_CORP_PUBKEY, notary = DUMMY_NOTARY)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -492,7 +486,7 @@ class CashTests {
|
||||
}
|
||||
|
||||
fun makeSpend(amount: Amount<Currency>, dest: PublicKey): WireTransaction {
|
||||
var tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
val tx = TransactionType.General.Builder(DUMMY_NOTARY)
|
||||
databaseTransaction(database) {
|
||||
vault.generateSpend(tx, amount, dest)
|
||||
}
|
||||
@ -618,8 +612,8 @@ class CashTests {
|
||||
assertEquals(vaultState0.ref, wtx.inputs[0])
|
||||
assertEquals(vaultState1.ref, wtx.inputs[1])
|
||||
assertEquals(vaultState2.ref, wtx.inputs[2])
|
||||
assertEquals(vaultState0.state.data.copy(owner = THEIR_PUBKEY_1, amount = 500.DOLLARS `issued by` defaultIssuer), wtx.outputs[0].data)
|
||||
assertEquals(vaultState2.state.data.copy(owner = THEIR_PUBKEY_1), wtx.outputs[1].data)
|
||||
assertEquals(vaultState0.state.data.copy(owner = THEIR_PUBKEY_1, amount = 500.DOLLARS `issued by` defaultIssuer), wtx.outputs[1].data)
|
||||
assertEquals(vaultState2.state.data.copy(owner = THEIR_PUBKEY_1), wtx.outputs[0].data)
|
||||
assertEquals(OUR_PUBKEY_1, wtx.commands.single { it.value is Cash.Commands.Move }.signers[0])
|
||||
}
|
||||
}
|
||||
|
@ -165,7 +165,9 @@ interface VaultService {
|
||||
}
|
||||
|
||||
/**
|
||||
* Fungible Asset operations
|
||||
* [InsufficientBalanceException] is thrown when a Cash Spending transaction fails because
|
||||
* there is insufficient quantity for a given currency (and optionally set of Issuer Parties).
|
||||
* Note: an [Amount] of [Currency] is only fungible for a given Issuer Party within a [FungibleAsset]
|
||||
**/
|
||||
@Throws(InsufficientBalanceException::class)
|
||||
fun generateSpend(tx: TransactionBuilder,
|
||||
|
@ -79,7 +79,8 @@ class ServerRPCOps(
|
||||
val builder: TransactionBuilder = TransactionType.General.Builder(null)
|
||||
// TODO: Have some way of restricting this to states the caller controls
|
||||
try {
|
||||
val (spendTX, keysForSigning) = services.vaultService.generateSpend(builder, req.amount.withoutIssuer(), req.recipient.owningKey)
|
||||
val (spendTX, keysForSigning) = services.vaultService.generateSpend(builder,
|
||||
req.amount.withoutIssuer(), req.recipient.owningKey, setOf(req.amount.token.issuer.party))
|
||||
|
||||
keysForSigning.forEach {
|
||||
val key = services.keyManagementService.keys[it] ?: throw IllegalStateException("Could not find signing key for ${it.toStringShort()}")
|
||||
|
@ -170,17 +170,22 @@ class NodeVaultService(private val services: ServiceHub) : SingletonSerializeAsT
|
||||
val coins = it.value
|
||||
val totalAmount = coins.map { it.state.data.amount }.sumOrThrow()
|
||||
deriveState(coins.first().state, totalAmount, to)
|
||||
}
|
||||
}.sortedBy { it.data.amount.quantity }
|
||||
|
||||
val outputs = if (change != null) {
|
||||
// Just copy a key across as the change key. In real life of course, this works but leaks private data.
|
||||
// In bitcoinj we derive a fresh key here and then shuffle the outputs to ensure it's hard to follow
|
||||
// value flows through the transaction graph.
|
||||
val changeKey = gathered.first().state.data.owner
|
||||
val existingOwner = gathered.first().state.data.owner
|
||||
// Add a change output and adjust the last output downwards.
|
||||
states.subList(0, states.lastIndex) +
|
||||
states.last().let { deriveState(it, it.data.amount - change, it.data.owner) } +
|
||||
deriveState(gathered.last().state, change, changeKey)
|
||||
states.last().let {
|
||||
val spent = it.data.amount.withoutIssuer() - change.withoutIssuer()
|
||||
deriveState(it, Amount(spent.quantity, it.data.amount.token), it.data.owner)
|
||||
} +
|
||||
states.last().let {
|
||||
deriveState(it, Amount(change.quantity, it.data.amount.token), existingOwner)
|
||||
}
|
||||
} else states
|
||||
|
||||
for (state in gathered) tx.addInputState(state)
|
||||
|
@ -1,35 +1,32 @@
|
||||
package com.r3corda.node.services
|
||||
|
||||
import com.google.common.jimfs.Configuration
|
||||
import com.google.common.jimfs.Jimfs
|
||||
import com.r3corda.core.contracts.*
|
||||
import com.r3corda.core.days
|
||||
import com.r3corda.core.node.ServiceHub
|
||||
import com.r3corda.core.node.recordTransactions
|
||||
import com.r3corda.core.node.services.VaultService
|
||||
import com.r3corda.core.protocols.ProtocolLogic
|
||||
import com.r3corda.core.protocols.ProtocolLogicRef
|
||||
import com.r3corda.core.protocols.ProtocolLogicRefFactory
|
||||
import com.r3corda.core.serialization.SingletonSerializeAsToken
|
||||
import com.r3corda.core.transactions.SignedTransaction
|
||||
import com.r3corda.core.utilities.DUMMY_NOTARY
|
||||
import com.r3corda.node.services.events.NodeSchedulerService
|
||||
import com.r3corda.node.services.persistence.DBCheckpointStorage
|
||||
import com.r3corda.node.services.statemachine.StateMachineManager
|
||||
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
|
||||
import com.r3corda.node.utilities.databaseTransaction
|
||||
import com.r3corda.testing.ALICE_KEY
|
||||
import com.r3corda.testing.node.*
|
||||
import com.r3corda.testing.node.InMemoryMessagingNetwork
|
||||
import com.r3corda.testing.node.MockKeyManagementService
|
||||
import com.r3corda.testing.node.TestClock
|
||||
import com.r3corda.testing.node.makeTestDataSourceProperties
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.jetbrains.exposed.sql.Database
|
||||
import org.junit.After
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import java.io.Closeable
|
||||
import java.nio.file.FileSystem
|
||||
import java.security.PublicKey
|
||||
import java.time.Clock
|
||||
import java.time.Instant
|
||||
@ -39,8 +36,6 @@ import java.util.concurrent.TimeUnit
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
// Use an in memory file system for testing attachment storage.
|
||||
val fs: FileSystem = Jimfs.newFileSystem(Configuration.unix())
|
||||
|
||||
val realClock: Clock = Clock.systemUTC()
|
||||
val stoppedClock = Clock.fixed(realClock.instant(), realClock.zone)
|
||||
@ -82,19 +77,7 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
|
||||
dataSource = dataSourceAndDatabase.first
|
||||
database = dataSourceAndDatabase.second
|
||||
|
||||
// Switched from InMemoryVault usage to NodeVault
|
||||
databaseTransaction(database) {
|
||||
val services1 = object : MockServices() {
|
||||
override val vaultService: VaultService = NodeVaultService(this)
|
||||
|
||||
override fun recordTransactions(txs: Iterable<SignedTransaction>) {
|
||||
for (stx in txs) {
|
||||
storageService.validatedTransactions.addTransaction(stx)
|
||||
vaultService.notify(stx.tx)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
val kms = MockKeyManagementService(ALICE_KEY)
|
||||
val mockMessagingService = InMemoryMessagingNetwork(false).InMemoryMessaging(false, InMemoryMessagingNetwork.Handle(0, "None"), AffinityExecutor.ServiceAffinityExecutor("test", 1), database)
|
||||
services = object : MockServiceHubInternal(overrideClock = testClock, keyManagement = kms, net = mockMessagingService), TestReference {
|
||||
|
0
src/main/kotlin/com/r3corda/demos/TraderDemo.kt
Normal file
0
src/main/kotlin/com/r3corda/demos/TraderDemo.kt
Normal file
Loading…
x
Reference in New Issue
Block a user