diff --git a/contracts/build.gradle b/contracts/build.gradle
index 486bdb9a6d..ae3daa7713 100644
--- a/contracts/build.gradle
+++ b/contracts/build.gradle
@@ -78,4 +78,6 @@ repositories {
dependencies {
compile project(':core')
+
+ testCompile 'junit:junit:4.12'
}
\ No newline at end of file
diff --git a/contracts/src/main/java/contracts/JavaCommercialPaper.java b/contracts/src/main/java/contracts/JavaCommercialPaper.java
index 7b283c31f7..39d1cd5d8f 100644
--- a/contracts/src/main/java/contracts/JavaCommercialPaper.java
+++ b/contracts/src/main/java/contracts/JavaCommercialPaper.java
@@ -88,7 +88,7 @@ public class JavaCommercialPaper implements Contract {
@Override
public Contract getContract() {
return JCP_PROGRAM_ID;
- //return SecureHash.Companion.sha256("java commercial paper (this should be a bytecode hash)");
+ //return SecureHash.sha256("java commercial paper (this should be a bytecode hash)");
}
@Override
diff --git a/contracts/src/main/kotlin/contracts/testing/TestUtils.kt b/contracts/src/main/kotlin/contracts/testing/TestUtils.kt
new file mode 100644
index 0000000000..febd5941b2
--- /dev/null
+++ b/contracts/src/main/kotlin/contracts/testing/TestUtils.kt
@@ -0,0 +1,53 @@
+package contracts.testing
+
+import contracts.*
+import core.contracts.Amount
+import core.contracts.Contract
+import core.crypto.NullPublicKey
+import core.crypto.Party
+import core.testing.DUMMY_NOTARY
+import core.testing.MINI_CORP
+import java.security.PublicKey
+import java.util.*
+
+// In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside
+// a sandbox. For unit tests we just have a hard-coded list.
+val TEST_PROGRAM_MAP: Map> = mapOf(
+ CASH_PROGRAM_ID to Cash::class.java,
+ CP_PROGRAM_ID to CommercialPaper::class.java,
+ JavaCommercialPaper.JCP_PROGRAM_ID to JavaCommercialPaper::class.java,
+ CROWDFUND_PROGRAM_ID to CrowdFund::class.java,
+ DUMMY_PROGRAM_ID to DummyContract::class.java,
+ IRS_PROGRAM_ID to InterestRateSwap::class.java
+)
+
+fun generateState(notary: Party = DUMMY_NOTARY) = DummyContract.State(Random().nextInt(), notary)
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// Defines a simple DSL for building pseudo-transactions (not the same as the wire protocol) for testing purposes.
+//
+// Define a transaction like this:
+//
+// transaction {
+// input { someExpression }
+// output { someExpression }
+// arg { someExpression }
+//
+// tweak {
+// ... same thing but works with a copy of the parent, can add inputs/outputs/args just within this scope.
+// }
+//
+// contract.accepts() -> should pass
+// contract `fails requirement` "some substring of the error message"
+// }
+//
+// TODO: Make it impossible to forget to test either a failure or an accept for each transaction{} block
+
+infix fun Cash.State.`owned by`(owner: PublicKey) = copy(owner = owner)
+infix fun Cash.State.`issued by`(party: Party) = copy(deposit = deposit.copy(party = party))
+infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
+infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = this.withOwner(new_owner)
+
+// Allows you to write 100.DOLLARS.CASH
+val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1, 2, 3), this, NullPublicKey, DUMMY_NOTARY)
diff --git a/node/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt b/contracts/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt
similarity index 93%
rename from node/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt
rename to contracts/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt
index bb123c82ce..6da66c4ab9 100644
--- a/node/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt
+++ b/contracts/src/main/kotlin/protocols/TwoPartyTradeProtocol.kt
@@ -1,7 +1,6 @@
package protocols
import co.paralleluniverse.fibers.Suspendable
-import com.google.common.util.concurrent.ListenableFuture
import contracts.Cash
import contracts.sumCashBy
import core.contracts.*
@@ -9,7 +8,6 @@ import core.crypto.DigitalSignature
import core.crypto.Party
import core.crypto.signWithECDSA
import core.messaging.SingleMessageRecipient
-import core.messaging.StateMachineManager
import core.node.NodeInfo
import core.protocols.ProtocolLogic
import core.random63BitValue
@@ -46,20 +44,6 @@ import java.security.SignatureException
object TwoPartyTradeProtocol {
val TRADE_TOPIC = "platform.trade"
- fun runSeller(smm: StateMachineManager, notary: NodeInfo,
- otherSide: SingleMessageRecipient, assetToSell: StateAndRef, price: Amount,
- myKeyPair: KeyPair, buyerSessionID: Long): ListenableFuture {
- val seller = Seller(otherSide, notary, assetToSell, price, myKeyPair, buyerSessionID)
- return smm.add("${TRADE_TOPIC}.seller", seller)
- }
-
- fun runBuyer(smm: StateMachineManager, notaryNode: NodeInfo,
- otherSide: SingleMessageRecipient, acceptablePrice: Amount, typeToBuy: Class,
- sessionID: Long): ListenableFuture {
- val buyer = Buyer(otherSide, notaryNode.identity, acceptablePrice, typeToBuy, sessionID)
- return smm.add("$TRADE_TOPIC.buyer", buyer)
- }
-
class UnacceptablePriceException(val givenPrice: Amount) : Exception()
class AssetMismatchException(val expectedTypeName: String, val typeName: String) : Exception() {
override fun toString() = "The submitted asset didn't match the expected type: $expectedTypeName vs $typeName"
diff --git a/node/src/test/kotlin/contracts/CashTests.kt b/contracts/src/test/kotlin/contracts/CashTests.kt
similarity index 99%
rename from node/src/test/kotlin/contracts/CashTests.kt
rename to contracts/src/test/kotlin/contracts/CashTests.kt
index 6ebfb55e52..864274c8d7 100644
--- a/node/src/test/kotlin/contracts/CashTests.kt
+++ b/contracts/src/test/kotlin/contracts/CashTests.kt
@@ -1,12 +1,13 @@
import contracts.Cash
import contracts.DummyContract
import contracts.InsufficientBalanceException
-import core.*
+import contracts.testing.`issued by`
+import contracts.testing.`owned by`
import core.contracts.*
import core.crypto.Party
import core.crypto.SecureHash
import core.serialization.OpaqueBytes
-import core.testutils.*
+import core.testing.*
import org.junit.Test
import java.security.PublicKey
import java.util.*
diff --git a/node/src/test/kotlin/contracts/CommercialPaperTests.kt b/contracts/src/test/kotlin/contracts/CommercialPaperTests.kt
similarity index 96%
rename from node/src/test/kotlin/contracts/CommercialPaperTests.kt
rename to contracts/src/test/kotlin/contracts/CommercialPaperTests.kt
index cb70b1f969..3b59e4dbfd 100644
--- a/node/src/test/kotlin/contracts/CommercialPaperTests.kt
+++ b/contracts/src/test/kotlin/contracts/CommercialPaperTests.kt
@@ -1,9 +1,13 @@
package contracts
-import core.*
+import contracts.testing.CASH
+import contracts.testing.`owned by`
import core.contracts.*
import core.crypto.SecureHash
-import core.testutils.*
+import core.days
+import core.node.services.testing.MockStorageService
+import core.seconds
+import core.testing.*
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.Parameterized
@@ -149,7 +153,7 @@ class CommercialPaperTestsGeneric {
signWith(DUMMY_NOTARY_KEY)
}
val stx = ptx.toSignedTransaction()
- stx.verifyToLedgerTransaction(MockIdentityService, attachments)
+ stx.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
val (alicesWalletTX, alicesWallet) = cashOutputsToWallet(
@@ -166,7 +170,7 @@ class CommercialPaperTestsGeneric {
ptx.signWith(MINI_CORP_KEY)
ptx.signWith(ALICE_KEY)
ptx.signWith(DUMMY_NOTARY_KEY)
- ptx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ ptx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
// Won't be validated.
@@ -182,7 +186,7 @@ class CommercialPaperTestsGeneric {
ptx.signWith(ALICE_KEY)
ptx.signWith(MINI_CORP_KEY)
ptx.signWith(DUMMY_NOTARY_KEY)
- return ptx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ return ptx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
val tooEarlyRedemption = makeRedeemTX(TEST_TX_TIME + 10.days)
diff --git a/node/src/test/kotlin/contracts/CrowdFundTests.kt b/contracts/src/test/kotlin/contracts/CrowdFundTests.kt
similarity index 95%
rename from node/src/test/kotlin/contracts/CrowdFundTests.kt
rename to contracts/src/test/kotlin/contracts/CrowdFundTests.kt
index 2b9a044bb8..eeba0593ae 100644
--- a/node/src/test/kotlin/contracts/CrowdFundTests.kt
+++ b/contracts/src/test/kotlin/contracts/CrowdFundTests.kt
@@ -1,9 +1,13 @@
package contracts
-import core.*
+import contracts.testing.CASH
+import contracts.testing.`owned by`
import core.contracts.*
import core.crypto.SecureHash
-import core.testutils.*
+import core.days
+import core.node.services.testing.MockStorageService
+import core.seconds
+import core.testing.*
import org.junit.Test
import java.time.Instant
import java.util.*
@@ -109,7 +113,7 @@ class CrowdFundTests {
signWith(MINI_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
}
- ptx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ ptx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
// let's give Alice some funds that she can invest
@@ -128,7 +132,7 @@ class CrowdFundTests {
ptx.signWith(ALICE_KEY)
ptx.signWith(DUMMY_NOTARY_KEY)
// this verify passes - the transaction contains an output cash, necessary to verify the fund command
- ptx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ ptx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
// Won't be validated.
@@ -143,7 +147,7 @@ class CrowdFundTests {
CrowdFund().generateClose(ptx, pledgeTX.outRef(0), miniCorpWallet)
ptx.signWith(MINI_CORP_KEY)
ptx.signWith(DUMMY_NOTARY_KEY)
- return ptx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ return ptx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
val tooEarlyClose = makeFundedTX(TEST_TX_TIME + 6.days)
diff --git a/node/src/test/kotlin/contracts/IRSTests.kt b/contracts/src/test/kotlin/contracts/IRSTests.kt
similarity index 99%
rename from node/src/test/kotlin/contracts/IRSTests.kt
rename to contracts/src/test/kotlin/contracts/IRSTests.kt
index 981fb9055c..ce5ebc7bb6 100644
--- a/node/src/test/kotlin/contracts/IRSTests.kt
+++ b/contracts/src/test/kotlin/contracts/IRSTests.kt
@@ -1,8 +1,9 @@
package contracts
-import core.*
import core.contracts.*
-import core.testutils.*
+import core.node.services.testing.MockStorageService
+import core.seconds
+import core.testing.*
import org.junit.Test
import java.math.BigDecimal
import java.time.LocalDate
@@ -236,7 +237,7 @@ class IRSTests {
signWith(MINI_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
}
- gtx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ gtx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
return genTX
}
@@ -320,7 +321,7 @@ class IRSTests {
signWith(MINI_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
}
- tx.toSignedTransaction().verifyToLedgerTransaction(MockIdentityService, attachments)
+ tx.toSignedTransaction().verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, attachments)
}
currentIRS = previousTXN.outputs.filterIsInstance().single()
println(currentIRS.prettyPrint())
diff --git a/core/build.gradle b/core/build.gradle
index 5894f309fe..d6551b4e4d 100644
--- a/core/build.gradle
+++ b/core/build.gradle
@@ -21,8 +21,15 @@ repositories {
}
}
+//noinspection GroovyAssignabilityCheck
+configurations {
+ quasar
+}
+
dependencies {
testCompile 'junit:junit:4.12'
+ testCompile 'org.assertj:assertj-core:3.4.1'
+ testCompile "commons-fileupload:commons-fileupload:1.3.1"
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
compile "org.jetbrains.kotlin:kotlin-reflect:$kotlin_version"
@@ -56,4 +63,40 @@ dependencies {
// For JSON
compile "com.fasterxml.jackson.core:jackson-databind:2.5.5"
+
+ // Quasar: for the bytecode rewriting for state machines.
+ quasar "co.paralleluniverse:quasar-core:${quasar_version}:jdk8@jar"
}
+
+
+tasks.withType(Test) {
+ jvmArgs "-javaagent:${configurations.quasar.singleFile}"
+ jvmArgs "-Dco.paralleluniverse.fibers.verifyInstrumentation"
+}
+tasks.withType(JavaExec) {
+ jvmArgs "-javaagent:${configurations.quasar.singleFile}"
+ jvmArgs "-Dco.paralleluniverse.fibers.verifyInstrumentation"
+}
+
+
+// These lines tell gradle to run the Quasar suspendables scanner to look for unannotated super methods
+// that have @Suspendable sub implementations. These tend to cause NPEs and are not caught by the verifier
+// NOTE: need to make sure the output isn't on the classpath or every other run it generates empty results, so
+// we explicitly delete to avoid that happening. We also need to turn off what seems to be a spurious warning in the IDE
+//
+// TODO: Make this task incremental, as it can be quite slow.
+
+//noinspection GroovyAssignabilityCheck
+task quasarScan(dependsOn: ['classes']) << {
+ ant.taskdef(name:'scanSuspendables', classname:'co.paralleluniverse.fibers.instrument.SuspendablesScanner',
+ classpath: "${sourceSets.main.output.classesDir}:${sourceSets.main.output.resourcesDir}:${configurations.runtime.asPath}")
+ delete "$sourceSets.main.output.resourcesDir/META-INF/suspendables", "$sourceSets.main.output.resourcesDir/META-INF/suspendable-supers"
+ ant.scanSuspendables(
+ auto:false,
+ suspendablesFile: "$sourceSets.main.output.resourcesDir/META-INF/suspendables",
+ supersFile: "$sourceSets.main.output.resourcesDir/META-INF/suspendable-supers") {
+ fileset(dir: sourceSets.main.output.classesDir)
+ }
+}
+
+jar.dependsOn quasarScan
\ No newline at end of file
diff --git a/core/src/main/kotlin/core/node/ServiceHub.kt b/core/src/main/kotlin/core/node/ServiceHub.kt
index ec36bb412c..73e491486b 100644
--- a/core/src/main/kotlin/core/node/ServiceHub.kt
+++ b/core/src/main/kotlin/core/node/ServiceHub.kt
@@ -3,8 +3,7 @@ package core.node
import core.contracts.*
import core.crypto.SecureHash
import core.messaging.MessagingService
-import core.node.services.IdentityService
-import core.node.subsystems.*
+import core.node.services.*
import core.utilities.RecordingMap
import java.time.Clock
@@ -24,7 +23,6 @@ interface ServiceHub {
val storageService: StorageService
val networkService: MessagingService
val networkMapCache: NetworkMapCache
- val monitoringService: MonitoringService
val clock: Clock
/**
diff --git a/core/src/main/kotlin/core/node/subsystems/NetworkMapCache.kt b/core/src/main/kotlin/core/node/services/NetworkMapCache.kt
similarity index 93%
rename from core/src/main/kotlin/core/node/subsystems/NetworkMapCache.kt
rename to core/src/main/kotlin/core/node/services/NetworkMapCache.kt
index f1e7e3f9e4..992198b3d0 100644
--- a/core/src/main/kotlin/core/node/subsystems/NetworkMapCache.kt
+++ b/core/src/main/kotlin/core/node/services/NetworkMapCache.kt
@@ -1,19 +1,13 @@
-package core.node.subsystems
+package core.node.services
import com.google.common.util.concurrent.ListenableFuture
import core.contracts.Contract
import core.crypto.Party
-import core.crypto.SecureHash
import core.messaging.MessagingService
import core.node.NodeInfo
-import core.node.services.*
-import core.serialization.deserialize
-import core.serialization.serialize
+import core.node.services.ServiceType
import org.slf4j.LoggerFactory
import java.security.PublicKey
-import java.security.SignatureException
-import java.util.*
-import javax.annotation.concurrent.ThreadSafe
/**
* A network map contains lists of nodes on the network along with information about their identity keys, services
diff --git a/core/src/main/kotlin/core/node/subsystems/Services.kt b/core/src/main/kotlin/core/node/services/Services.kt
similarity index 93%
rename from core/src/main/kotlin/core/node/subsystems/Services.kt
rename to core/src/main/kotlin/core/node/services/Services.kt
index f9978f71fa..1f4fdf70eb 100644
--- a/core/src/main/kotlin/core/node/subsystems/Services.kt
+++ b/core/src/main/kotlin/core/node/services/Services.kt
@@ -1,12 +1,9 @@
-package core.node.subsystems
+package core.node.services
-import com.codahale.metrics.MetricRegistry
-import core.*
import core.contracts.*
import core.crypto.Party
import core.crypto.SecureHash
import core.node.services.AttachmentStorage
-import core.node.storage.CheckpointStorage
import java.security.KeyPair
import java.security.PrivateKey
import java.security.PublicKey
@@ -128,8 +125,6 @@ interface StorageService {
*/
val validatedTransactions: MutableMap
- val checkpointStorage: CheckpointStorage
-
/** Provides access to storage of arbitrary JAR files (which may contain only data, no code). */
val attachments: AttachmentStorage
@@ -141,9 +136,4 @@ interface StorageService {
val myLegalIdentityKey: KeyPair
}
-/**
- * Provides access to various metrics and ways to notify monitoring services of things, for sysadmin purposes.
- * This is not an interface because it is too lightweight to bother mocking out.
- */
-class MonitoringService(val metrics: MetricRegistry)
diff --git a/core/src/main/kotlin/core/node/services/testing/MockServices.kt b/core/src/main/kotlin/core/node/services/testing/MockServices.kt
new file mode 100644
index 0000000000..737be869af
--- /dev/null
+++ b/core/src/main/kotlin/core/node/services/testing/MockServices.kt
@@ -0,0 +1,113 @@
+package core.node.services.testing
+
+import core.contracts.Attachment
+import core.contracts.SignedTransaction
+import core.crypto.Party
+import core.crypto.SecureHash
+import core.crypto.generateKeyPair
+import core.crypto.sha256
+import core.node.services.AttachmentStorage
+import core.node.services.IdentityService
+import core.node.services.KeyManagementService
+import core.node.services.StorageService
+import core.utilities.RecordingMap
+import org.slf4j.LoggerFactory
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.File
+import java.io.InputStream
+import java.security.KeyPair
+import java.security.PrivateKey
+import java.security.PublicKey
+import java.util.*
+import java.util.jar.JarInputStream
+import javax.annotation.concurrent.ThreadSafe
+
+@ThreadSafe
+class MockIdentityService(val identities: List) : IdentityService {
+ private val keyToParties: Map
+ get() = synchronized(identities) { identities.associateBy { it.owningKey } }
+ private val nameToParties: Map
+ get() = synchronized(identities) { identities.associateBy { it.name } }
+
+ override fun registerIdentity(party: Party) { throw UnsupportedOperationException() }
+ override fun partyFromKey(key: PublicKey): Party? = keyToParties[key]
+ override fun partyFromName(name: String): Party? = nameToParties[name]
+}
+
+
+class MockKeyManagementService(vararg initialKeys: KeyPair) : KeyManagementService {
+ override val keys: MutableMap
+
+ init {
+ keys = initialKeys.map { it.public to it.private }.toMap(HashMap())
+ }
+
+ val nextKeys = LinkedList()
+
+ override fun freshKey(): KeyPair {
+ val k = nextKeys.poll() ?: generateKeyPair()
+ keys[k.public] = k.private
+ return k
+ }
+}
+
+class MockAttachmentStorage : AttachmentStorage {
+ val files = HashMap()
+
+ override fun openAttachment(id: SecureHash): Attachment? {
+ val f = files[id] ?: return null
+ return object : Attachment {
+ override fun open(): InputStream = ByteArrayInputStream(f)
+ override val id: SecureHash = id
+ }
+ }
+
+ override fun importAttachment(jar: InputStream): SecureHash {
+ // JIS makes read()/readBytes() return bytes of the current file, but we want to hash the entire container here.
+ require(jar !is JarInputStream)
+
+ val bytes = run {
+ val s = ByteArrayOutputStream()
+ jar.copyTo(s)
+ s.close()
+ s.toByteArray()
+ }
+ val sha256 = bytes.sha256()
+ if (files.containsKey(sha256))
+ throw FileAlreadyExistsException(File("!! MOCK FILE NAME"))
+ files[sha256] = bytes
+ return sha256
+ }
+}
+
+
+@ThreadSafe
+class MockStorageService(override val attachments: AttachmentStorage = MockAttachmentStorage(),
+ override val myLegalIdentityKey: KeyPair = generateKeyPair(),
+ override val myLegalIdentity: Party = Party("Unit test party", myLegalIdentityKey.public),
+// This parameter is for unit tests that want to observe operation details.
+ val recordingAs: (String) -> String = { tableName -> "" })
+: StorageService {
+ protected val tables = HashMap>()
+
+ private fun getMapOriginal(tableName: String): MutableMap {
+ synchronized(tables) {
+ @Suppress("UNCHECKED_CAST")
+ return tables.getOrPut(tableName) {
+ recorderWrap(Collections.synchronizedMap(HashMap()), tableName)
+ } as MutableMap
+ }
+ }
+
+ private fun recorderWrap(map: MutableMap, tableName: String): MutableMap {
+ if (recordingAs(tableName) != "")
+ return RecordingMap(map, LoggerFactory.getLogger("recordingmap.${recordingAs(tableName)}"))
+ else
+ return map
+ }
+
+ override val validatedTransactions: MutableMap
+ get() = getMapOriginal("validated-transactions")
+
+}
diff --git a/core/src/main/kotlin/core/serialization/Kryo.kt b/core/src/main/kotlin/core/serialization/Kryo.kt
index bf20a92881..37acca91ae 100644
--- a/core/src/main/kotlin/core/serialization/Kryo.kt
+++ b/core/src/main/kotlin/core/serialization/Kryo.kt
@@ -8,7 +8,6 @@ import com.esotericsoftware.kryo.Serializer
import com.esotericsoftware.kryo.io.Input
import com.esotericsoftware.kryo.io.Output
import com.esotericsoftware.kryo.serializers.JavaSerializer
-import core.*
import core.contracts.*
import core.crypto.SecureHash
import core.crypto.generateKeyPair
diff --git a/node/src/test/kotlin/core/testutils/TestUtils.kt b/core/src/main/kotlin/core/testing/TestUtils.kt
similarity index 84%
rename from node/src/test/kotlin/core/testutils/TestUtils.kt
rename to core/src/main/kotlin/core/testing/TestUtils.kt
index 76a7c193dc..ea76bdc1f4 100644
--- a/node/src/test/kotlin/core/testutils/TestUtils.kt
+++ b/core/src/main/kotlin/core/testing/TestUtils.kt
@@ -1,17 +1,15 @@
@file:Suppress("UNUSED_PARAMETER", "UNCHECKED_CAST")
-package core.testutils
+package core.testing
import com.google.common.base.Throwables
import com.google.common.net.HostAndPort
-import contracts.*
import core.*
import core.contracts.*
import core.crypto.*
-import core.node.AbstractNode
import core.serialization.serialize
-import core.testing.MockIdentityService
-import core.visualiser.GraphVisualiser
+import core.node.services.testing.MockIdentityService
+import core.node.services.testing.MockStorageService
import java.net.ServerSocket
import java.security.KeyPair
import java.security.PublicKey
@@ -73,31 +71,10 @@ val DUMMY_NOTARY = Party("Notary Service", DUMMY_NOTARY_KEY.public)
val ALL_TEST_KEYS = listOf(MEGA_CORP_KEY, MINI_CORP_KEY, ALICE_KEY, BOB_KEY, DUMMY_NOTARY_KEY)
-val MockIdentityService = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
+val MOCK_IDENTITY_SERVICE = MockIdentityService(listOf(MEGA_CORP, MINI_CORP, DUMMY_NOTARY))
-// In a real system this would be a persistent map of hash to bytecode and we'd instantiate the object as needed inside
-// a sandbox. For unit tests we just have a hard-coded list.
-val TEST_PROGRAM_MAP: Map> = mapOf(
- CASH_PROGRAM_ID to Cash::class.java,
- CP_PROGRAM_ID to CommercialPaper::class.java,
- JavaCommercialPaper.JCP_PROGRAM_ID to JavaCommercialPaper::class.java,
- CROWDFUND_PROGRAM_ID to CrowdFund::class.java,
- DUMMY_PROGRAM_ID to DummyContract::class.java,
- IRS_PROGRAM_ID to InterestRateSwap::class.java
-)
-
-fun generateState(notary: Party = DUMMY_NOTARY) = DummyContract.State(Random().nextInt(), notary)
fun generateStateRef() = StateRef(SecureHash.randomSHA256(), 0)
-fun issueState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef {
- 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 StateRef(stx.id, 0)
-}
-
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Defines a simple DSL for building pseudo-transactions (not the same as the wire protocol) for testing purposes.
@@ -119,14 +96,6 @@ fun issueState(node: AbstractNode, notary: Party = DUMMY_NOTARY): StateRef {
//
// TODO: Make it impossible to forget to test either a failure or an accept for each transaction{} block
-infix fun Cash.State.`owned by`(owner: PublicKey) = copy(owner = owner)
-infix fun Cash.State.`issued by`(party: Party) = copy(deposit = deposit.copy(party = party))
-infix fun CommercialPaper.State.`owned by`(owner: PublicKey) = this.copy(owner = owner)
-infix fun ICommercialPaperState.`owned by`(new_owner: PublicKey) = this.withOwner(new_owner)
-
-// Allows you to write 100.DOLLARS.CASH
-val Amount.CASH: Cash.State get() = Cash.State(MINI_CORP.ref(1, 2, 3), this, NullPublicKey, DUMMY_NOTARY)
-
class LabeledOutput(val label: String?, val state: ContractState) {
override fun toString() = state.toString() + (if (label != null) " ($label)" else "")
override fun equals(other: Any?) = other is LabeledOutput && state.equals(other.state)
@@ -143,7 +112,7 @@ abstract class AbstractTransactionForTest {
open fun output(label: String? = null, s: () -> ContractState) = LabeledOutput(label, s()).apply { outStates.add(this) }
protected fun commandsToAuthenticatedObjects(): List> {
- return commands.map { AuthenticatedObject(it.signers, it.signers.mapNotNull { MockIdentityService.partyFromKey(it) }, it.value) }
+ return commands.map { AuthenticatedObject(it.signers, it.signers.mapNotNull { MOCK_IDENTITY_SERVICE.partyFromKey(it) }, it.value) }
}
fun attachment(attachmentID: SecureHash) {
@@ -177,7 +146,7 @@ open class TransactionForTest : AbstractTransactionForTest() {
protected fun runCommandsAndVerify(time: Instant) {
val cmds = commandsToAuthenticatedObjects()
- val tx = TransactionForVerification(inStates, outStates.map { it.state }, emptyList(), cmds, SecureHash.randomSHA256())
+ val tx = TransactionForVerification(inStates, outStates.map { it.state }, emptyList(), cmds, SecureHash.Companion.randomSHA256())
tx.verify()
}
@@ -334,8 +303,8 @@ class TransactionGroupDSL(private val stateType: Class) {
}
fun toTransactionGroup() = TransactionGroup(
- txns.map { it.toLedgerTransaction(MockIdentityService, MockStorageService().attachments) }.toSet(),
- rootTxns.map { it.toLedgerTransaction(MockIdentityService, MockStorageService().attachments) }.toSet()
+ txns.map { it.toLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) }.toSet(),
+ rootTxns.map { it.toLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments) }.toSet()
)
class Failed(val index: Int, cause: Throwable) : Exception("Transaction $index didn't verify", cause)
@@ -361,11 +330,6 @@ class TransactionGroupDSL(private val stateType: Class) {
return e
}
- fun visualise() {
- @Suppress("CAST_NEVER_SUCCEEDS")
- GraphVisualiser(this as TransactionGroupDSL).display()
- }
-
fun signAll(txnsToSign: List = txns, vararg extraKeys: KeyPair): List {
return txnsToSign.map { wtx ->
val allPubKeys = wtx.commands.flatMap { it.signers }.toMutableSet()
diff --git a/node/src/main/resources/core/node/cities.txt b/core/src/main/resources/core/node/cities.txt
similarity index 100%
rename from node/src/main/resources/core/node/cities.txt
rename to core/src/main/resources/core/node/cities.txt
diff --git a/node/src/test/resources/core/node/isolated.jar b/core/src/main/resources/core/node/isolated.jar
similarity index 100%
rename from node/src/test/resources/core/node/isolated.jar
rename to core/src/main/resources/core/node/isolated.jar
diff --git a/node/src/test/kotlin/core/TransactionGroupTests.kt b/core/src/test/kotlin/core/contracts/TransactionGroupTests.kt
similarity index 62%
rename from node/src/test/kotlin/core/TransactionGroupTests.kt
rename to core/src/test/kotlin/core/contracts/TransactionGroupTests.kt
index f14e0097fb..32694c393d 100644
--- a/node/src/test/kotlin/core/TransactionGroupTests.kt
+++ b/core/src/test/kotlin/core/contracts/TransactionGroupTests.kt
@@ -1,15 +1,43 @@
-package core
+package core.contracts
-import contracts.Cash
-import core.contracts.*
-import core.testutils.*
+import core.crypto.Party
+import core.crypto.SecureHash
+import core.node.services.testing.MockStorageService
+import core.testing.*
import org.junit.Test
+import java.security.PublicKey
+import java.security.SecureRandom
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotEquals
+val TEST_PROGRAM_ID = TransactionGroupTests.TestCash()
+
class TransactionGroupTests {
- val A_THOUSAND_POUNDS = Cash.State(MINI_CORP.ref(1, 2, 3), 1000.POUNDS, MINI_CORP_PUBKEY, DUMMY_NOTARY)
+ val A_THOUSAND_POUNDS = TestCash.State(MINI_CORP.ref(1, 2, 3), 1000.POUNDS, MINI_CORP_PUBKEY, DUMMY_NOTARY)
+
+ class TestCash : Contract {
+ override val legalContractReference = SecureHash.sha256("TestCash")
+
+ override fun verify(tx: TransactionForVerification) {
+ }
+
+ data class State(
+ val deposit: PartyAndReference,
+ val amount: Amount,
+ override val owner: PublicKey,
+ override val notary: Party) : OwnableState {
+ override val contract: Contract = TEST_PROGRAM_ID
+ override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
+ }
+ interface Commands : CommandData {
+ class Move() : TypeOnlyCommandData(), Commands
+ data class Issue(val nonce: Long = SecureRandom.getInstanceStrong().nextLong()) : Commands
+ data class Exit(val amount: Amount) : Commands
+ }
+ }
+
+ infix fun TestCash.State.`owned by`(owner: PublicKey) = copy(owner = owner)
@Test
fun success() {
@@ -21,13 +49,13 @@ class TransactionGroupTests {
transaction {
input("£1000")
output("alice's £1000") { A_THOUSAND_POUNDS `owned by` ALICE_PUBKEY }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() }
}
transaction {
input("alice's £1000")
- arg(ALICE_PUBKEY) { Cash.Commands.Move() }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Exit(1000.POUNDS) }
+ arg(ALICE_PUBKEY) { TestCash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) }
}
verify()
@@ -39,7 +67,7 @@ class TransactionGroupTests {
transactionGroup {
val t = transaction {
output("cash") { A_THOUSAND_POUNDS }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() }
}
val conflict1 = transaction {
@@ -47,7 +75,7 @@ class TransactionGroupTests {
val HALF = A_THOUSAND_POUNDS.copy(amount = 500.POUNDS) `owned by` BOB_PUBKEY
output { HALF }
output { HALF }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() }
}
verify()
@@ -58,7 +86,7 @@ class TransactionGroupTests {
val HALF = A_THOUSAND_POUNDS.copy(amount = 500.POUNDS) `owned by` ALICE_PUBKEY
output { HALF }
output { HALF }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() }
}
assertNotEquals(conflict1, conflict2)
@@ -77,7 +105,7 @@ class TransactionGroupTests {
val tg = transactionGroup {
transaction {
output("cash") { A_THOUSAND_POUNDS }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() }
}
transaction {
@@ -92,7 +120,7 @@ class TransactionGroupTests {
tg.txns += TransactionBuilder().apply {
addInputState(input)
addOutputState(A_THOUSAND_POUNDS)
- addCommand(Cash.Commands.Move(), BOB_PUBKEY)
+ addCommand(TestCash.Commands.Move(), BOB_PUBKEY)
}.toWireTransaction()
val e = assertFailsWith(TransactionResolutionException::class) {
@@ -113,7 +141,7 @@ class TransactionGroupTests {
input("£1000")
input("£1000")
output { A_THOUSAND_POUNDS.copy(amount = A_THOUSAND_POUNDS.amount * 2) }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() }
}
assertFailsWith(TransactionConflictException::class) {
@@ -127,25 +155,25 @@ class TransactionGroupTests {
val signedTxns: List = transactionGroup {
transaction {
output("£1000") { A_THOUSAND_POUNDS }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Issue() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Issue() }
}
transaction {
input("£1000")
output("alice's £1000") { A_THOUSAND_POUNDS `owned by` ALICE_PUBKEY }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Move() }
}
transaction {
input("alice's £1000")
- arg(ALICE_PUBKEY) { Cash.Commands.Move() }
- arg(MINI_CORP_PUBKEY) { Cash.Commands.Exit(1000.POUNDS) }
+ arg(ALICE_PUBKEY) { TestCash.Commands.Move() }
+ arg(MINI_CORP_PUBKEY) { TestCash.Commands.Exit(1000.POUNDS) }
}
}.signAll()
// Now go through the conversion -> verification path with them.
val ltxns = signedTxns.map {
- it.verifyToLedgerTransaction(MockIdentityService, MockStorageService().attachments)
+ it.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments)
}.toSet()
TransactionGroup(ltxns, emptySet()).verify()
}
diff --git a/node/src/test/java/core/crypto/Base58Test.java b/core/src/test/kotlin/core/crypto/Base58Test.java
similarity index 100%
rename from node/src/test/java/core/crypto/Base58Test.java
rename to core/src/test/kotlin/core/crypto/Base58Test.java
diff --git a/node/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt b/core/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt
similarity index 87%
rename from node/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt
rename to core/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt
index df29092342..e24e12ef23 100644
--- a/node/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt
+++ b/core/src/test/kotlin/core/node/AttachmentClassLoaderTests.kt
@@ -1,15 +1,13 @@
package core.node
-import contracts.DUMMY_PROGRAM_ID
-import contracts.DummyContract
-import core.*
import core.contracts.*
import core.crypto.Party
import core.crypto.SecureHash
import core.node.services.AttachmentStorage
+import core.node.services.testing.MockAttachmentStorage
import core.serialization.*
-import core.testutils.DUMMY_NOTARY
-import core.testutils.MEGA_CORP
+import core.testing.DUMMY_NOTARY
+import core.testing.MEGA_CORP
import org.apache.commons.io.IOUtils
import org.junit.Test
import java.io.ByteArrayInputStream
@@ -26,11 +24,36 @@ interface DummyContractBackdoor {
fun inspectState(state: ContractState): Int
}
+val ATTACHMENT_TEST_PROGRAM_ID = AttachmentClassLoaderTests.AttachmentDummyContract()
+
class AttachmentClassLoaderTests {
companion object {
val ISOLATED_CONTRACTS_JAR_PATH = AttachmentClassLoaderTests::class.java.getResource("isolated.jar")
}
+ class AttachmentDummyContract : Contract {
+ class State(val magicNumber: Int = 0,
+ override val notary: Party) : ContractState {
+ override val contract = ATTACHMENT_TEST_PROGRAM_ID
+ }
+
+ interface Commands : CommandData {
+ class Create : TypeOnlyCommandData(), Commands
+ }
+
+ override fun verify(tx: TransactionForVerification) {
+ // Always accepts.
+ }
+
+ // The "empty contract"
+ override val legalContractReference: SecureHash = SecureHash.sha256("")
+
+ fun generateInitial(owner: PartyAndReference, magicNumber: Int, notary: Party): TransactionBuilder {
+ val state = State(magicNumber, notary)
+ return TransactionBuilder().withItems(state, Command(Commands.Create(), owner.party.owningKey))
+ }
+ }
+
fun importJar(storage: AttachmentStorage) = ISOLATED_CONTRACTS_JAR_PATH.openStream().use { storage.importAttachment(it) }
// These ClassLoaders work together to load 'AnotherDummyContract' in a disposable way, such that even though
@@ -123,7 +146,7 @@ class AttachmentClassLoaderTests {
@Test
fun `verify that contract DummyContract is in classPath`() {
- val contractClass = Class.forName("contracts.DummyContract")
+ val contractClass = Class.forName("core.node.AttachmentClassLoaderTests\$AttachmentDummyContract")
val contract = contractClass.newInstance() as Contract
assertNotNull(contract)
@@ -186,13 +209,13 @@ class AttachmentClassLoaderTests {
@Test
fun `test serialization of WireTransaction with statically loaded contract`() {
- val tx = DUMMY_PROGRAM_ID.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
+ val tx = ATTACHMENT_TEST_PROGRAM_ID.generateInitial(MEGA_CORP.ref(0), 42, DUMMY_NOTARY)
val wireTransaction = tx.toWireTransaction()
val bytes = wireTransaction.serialize()
val copiedWireTransaction = bytes.deserialize()
assertEquals(1, copiedWireTransaction.outputs.size)
- assertEquals(42, (copiedWireTransaction.outputs[0] as DummyContract.State).magicNumber)
+ assertEquals(42, (copiedWireTransaction.outputs[0] as AttachmentDummyContract.State).magicNumber)
}
@Test
diff --git a/node/src/test/kotlin/core/serialization/KryoTests.kt b/core/src/test/kotlin/core/serialization/KryoTests.kt
similarity index 100%
rename from node/src/test/kotlin/core/serialization/KryoTests.kt
rename to core/src/test/kotlin/core/serialization/KryoTests.kt
diff --git a/core/src/test/kotlin/core/serialization/SerializationTokenTest.kt b/core/src/test/kotlin/core/serialization/SerializationTokenTest.kt
index 64431bb830..346364457b 100644
--- a/core/src/test/kotlin/core/serialization/SerializationTokenTest.kt
+++ b/core/src/test/kotlin/core/serialization/SerializationTokenTest.kt
@@ -74,6 +74,7 @@ class SerializationTokenTest {
@Test(expected = IllegalStateException::class)
fun `unannotated throws`() {
+ @Suppress("UNUSED_VARIABLE")
val tokenizableBefore = UnannotatedSerializeAsSingletonToken()
}
}
\ No newline at end of file
diff --git a/node/src/test/kotlin/core/serialization/TransactionSerializationTests.kt b/core/src/test/kotlin/core/serialization/TransactionSerializationTests.kt
similarity index 58%
rename from node/src/test/kotlin/core/serialization/TransactionSerializationTests.kt
rename to core/src/test/kotlin/core/serialization/TransactionSerializationTests.kt
index 5c4999daa1..5c2fd978ae 100644
--- a/node/src/test/kotlin/core/serialization/TransactionSerializationTests.kt
+++ b/core/src/test/kotlin/core/serialization/TransactionSerializationTests.kt
@@ -1,21 +1,48 @@
package core.serialization
-import contracts.Cash
-import core.*
import core.contracts.*
-import core.testutils.*
+import core.crypto.Party
+import core.crypto.SecureHash
+import core.node.services.testing.MockStorageService
+import core.seconds
+import core.testing.*
import org.junit.Before
import org.junit.Test
+import java.security.PublicKey
+import java.security.SecureRandom
import java.security.SignatureException
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
+val TEST_PROGRAM_ID = TransactionSerializationTests.TestCash()
+
class TransactionSerializationTests {
- // Simple TX that takes 1000 pounds from me and sends 600 to someone else (with 400 change).
+ class TestCash : Contract {
+ override val legalContractReference = SecureHash.sha256("TestCash")
+
+ override fun verify(tx: TransactionForVerification) {
+ }
+
+ data class State(
+ val deposit: PartyAndReference,
+ val amount: Amount,
+ override val owner: PublicKey,
+ override val notary: Party) : OwnableState {
+ override val contract: Contract = TEST_PROGRAM_ID
+ override fun withNewOwner(newOwner: PublicKey) = Pair(Commands.Move(), copy(owner = newOwner))
+ }
+ interface Commands : CommandData {
+ class Move() : TypeOnlyCommandData(), Commands
+ data class Issue(val nonce: Long = SecureRandom.getInstanceStrong().nextLong()) : Commands
+ data class Exit(val amount: Amount) : Commands
+ }
+ }
+
+ // Simple TX that takes 1000 pounds from me and sends 600 to someone else (with 400 change).
// It refers to a fake TX/state that we don't bother creating here.
val depositRef = MINI_CORP.ref(1)
- val outputState = Cash.State(depositRef, 600.POUNDS, DUMMY_PUBKEY_1, DUMMY_NOTARY)
- val changeState = Cash.State(depositRef, 400.POUNDS, TestUtils.keypair.public, DUMMY_NOTARY)
+ val outputState = TestCash.State(depositRef, 600.POUNDS, DUMMY_PUBKEY_1, DUMMY_NOTARY)
+ val changeState = TestCash.State(depositRef, 400.POUNDS, TestUtils.keypair.public, DUMMY_NOTARY)
val fakeStateRef = generateStateRef()
lateinit var tx: TransactionBuilder
@@ -23,7 +50,7 @@ class TransactionSerializationTests {
@Before
fun setup() {
tx = TransactionBuilder().withItems(
- fakeStateRef, outputState, changeState, Command(Cash.Commands.Move(), arrayListOf(TestUtils.keypair.public))
+ fakeStateRef, outputState, changeState, Command(TestCash.Commands.Move(), arrayListOf(TestUtils.keypair.public))
)
}
@@ -60,7 +87,7 @@ class TransactionSerializationTests {
// If the signature was replaced in transit, we don't like it.
assertFailsWith(SignatureException::class) {
val tx2 = TransactionBuilder().withItems(fakeStateRef, outputState, changeState,
- Command(Cash.Commands.Move(), TestUtils.keypair2.public))
+ Command(TestCash.Commands.Move(), TestUtils.keypair2.public))
tx2.signWith(TestUtils.keypair2)
signedTX.copy(sigs = tx2.toSignedTransaction().sigs).verify()
@@ -73,7 +100,7 @@ class TransactionSerializationTests {
tx.signWith(TestUtils.keypair)
tx.signWith(DUMMY_NOTARY_KEY)
val stx = tx.toSignedTransaction()
- val ltx = stx.verifyToLedgerTransaction(MockIdentityService, MockStorageService().attachments)
+ val ltx = stx.verifyToLedgerTransaction(MOCK_IDENTITY_SERVICE, MockStorageService().attachments)
assertEquals(tx.commands().map { it.value }, ltx.commands.map { it.value })
assertEquals(tx.inputStates(), ltx.inputs)
assertEquals(tx.outputStates(), ltx.outputs)
diff --git a/node/src/test/kotlin/core/utilities/CollectionExtensionTests.kt b/core/src/test/kotlin/core/utilities/CollectionExtensionTests.kt
similarity index 100%
rename from node/src/test/kotlin/core/utilities/CollectionExtensionTests.kt
rename to core/src/test/kotlin/core/utilities/CollectionExtensionTests.kt
diff --git a/docs/build/html/api/alltypes/index.html b/docs/build/html/api/alltypes/index.html
index c3ff70f22b..c5d370f7c6 100644
--- a/docs/build/html/api/alltypes/index.html
+++ b/docs/build/html/api/alltypes/index.html
@@ -9,7 +9,7 @@
-core.utilities.ANSIProgressRenderer |
+node.utilities.ANSIProgressRenderer
Knows how to render a ProgressTracker to the terminal using coloured, emoji-fied output. Useful when writing small
command line tools, demos, tests etc. Just set the progressTracker field and it will go ahead and start drawing
@@ -18,20 +18,20 @@ if the terminal supports it. Otherwise it just prints out the name of the step w
|
-api.APIServer |
+node.api.APIServer
Top level interface to external interaction with the distributed ledger.
|
-api.APIServerImpl |
+node.internal.APIServerImpl
|
-core.node.AbstractNode |
+node.internal.AbstractNode
A base node implementation that can be customised either for production (with real implementations that do real
I/O), or a mock implementation suitable for unit test environments.
@@ -39,7 +39,7 @@ I/O), or a mock implementation suitable for unit test environments.
|
-core.node.services.AbstractNodeService |
+node.services.api.AbstractNodeService
Abstract superclass for services that a node can host, which provides helper functions.
|
@@ -54,7 +54,7 @@ fields such as replyTo and replyToTopic.
-core.node.AcceptsFileUpload |
+node.services.api.AcceptsFileUpload
A service that implements AcceptsFileUpload can have new binary data provided to it via an HTTP upload.
|
@@ -69,14 +69,14 @@ We dont actually do anything with this yet though, so its ignored for now.
-core.utilities.AddOrRemove |
+node.utilities.AddOrRemove
Enum for when adding/removing something, for example adding or removing an entry in a directory.
|
-core.utilities.AffinityExecutor |
+node.utilities.AffinityExecutor
An extended executor interface that supports thread affinity assertions and short circuiting. This can be useful
for ensuring code runs on the right thread, and also for unit testing.
@@ -98,7 +98,7 @@ for ensuring code runs on the right thread, and also for unit testing.
|
-core.node.subsystems.ArtemisMessagingService |
+node.services.messaging.ArtemisMessagingService
This class implements the MessagingService API using Apache Artemis, the successor to their ActiveMQ product.
Artemis is a message queue broker and here, we embed the entire server inside our own process. Nodes communicate
@@ -117,7 +117,7 @@ of how attachments are meant to be used include:
|
-core.node.servlets.AttachmentDownloadServlet |
+node.servlets.AttachmentDownloadServlet
Allows the node administrator to either download full attachment zips, or individual files within those zips.
|
@@ -195,13 +195,13 @@ the same transaction.
-core.node.storage.Checkpoint |
+node.services.api.Checkpoint
|
-core.node.storage.CheckpointStorage |
+node.services.api.CheckpointStorage
Thread-safe storage of fiber checkpoints.
|
@@ -235,7 +235,7 @@ the same transaction.
-api.Config |
+node.servlets.Config
Primary purpose is to install Kotlin extensions for Jackson ObjectMapper so data classes work
and to organise serializers / deserializers for java.time.* classes as necessary
@@ -243,7 +243,7 @@ and to organise serializers / deserializers for java.time.* classes as necessary
|
-core.node.ConfigurationException |
+node.internal.ConfigurationException
|
@@ -259,20 +259,20 @@ timestamp attached to the transaction itself i.e. it is NOT necessarily the curr
-api.ContractClassRef |
+node.api.ContractClassRef
|
-api.ContractDefRef |
+node.api.ContractDefRef
Encapsulates the contract type. e.g. Cash or CommercialPaper etc.
|
-api.ContractLedgerRef |
+node.api.ContractLedgerRef
|
@@ -303,14 +303,14 @@ return the funds to the pledge-makers (if the target has not been reached).
-core.node.servlets.DataUploadServlet |
+node.servlets.DataUploadServlet
Accepts binary streams, finds the right AcceptsFileUpload implementor and hands the stream off to it.
|
-core.node.subsystems.DataVendingService |
+node.services.persistence.DataVendingService
This class sets up network message handlers for requests from peers for data keyed by hash. It is a piece of simple
glue that sits between the network layer and the database layer.
@@ -407,7 +407,7 @@ building partially signed transactions.
|
-core.node.subsystems.E2ETestKeyManagementService |
+node.services.keys.E2ETestKeyManagementService
A simple in-memory KMS that doesnt bother saving keys to disk. A real implementation would:
|
@@ -534,7 +534,7 @@ that would divide into (eg annually = 1, semiannual = 2, monthly = 12 etc).
-core.testing.IRSSimulation |
+node.internal.testing.IRSSimulation
A simulation in which banks execute interest rate swaps with each other, including the fixing events.
|
@@ -558,14 +558,14 @@ set via the constructor and the class is immutable.
-core.node.subsystems.InMemoryIdentityService |
+node.services.identity.InMemoryIdentityService
Simple identity service which caches parties and provides functionality for efficient lookup.
|
-core.testing.InMemoryMessagingNetwork |
+node.services.network.InMemoryMessagingNetwork
An in-memory network allows you to manufacture InMemoryMessagings for a set of participants. Each
InMemoryMessaging maintains a queue of messages it has received, and a background thread that dispatches
@@ -576,14 +576,14 @@ testing).
|
-core.node.subsystems.InMemoryNetworkMapCache |
+node.services.network.InMemoryNetworkMapCache
Extremely simple in-memory cache of the network map.
|
-core.node.services.InMemoryNetworkMapService |
+node.services.network.InMemoryNetworkMapService
|
@@ -649,7 +649,7 @@ This is just a representation of a vanilla Fixed vs Floating (same currency) IRS
-core.utilities.JsonSupport |
+node.utilities.JsonSupport
Utilities and serialisers for working with JSON representations of basic types. This adds Jackson support for
the java.time API, some core types, and Kotlin data classes.
@@ -657,7 +657,7 @@ the java.time API, some core types, and Kotlin data classes.
|
-core.node.subsystems.KeyManagementService |
+core.node.services.KeyManagementService
The KMS is responsible for storing and using private keys to sign things. An implementation of this may, for example,
call out to a hardware security module that enforces various auditing and frequency-of-use requirements.
@@ -765,7 +765,7 @@ may let you cast the returned future to an object that lets you get status info.
|
-core.testing.MockIdentityService |
+core.testservices.MockIdentityService
Scaffolding: a dummy identity service that just expects to have identities loaded off disk or found elsewhere.
This class allows the provided list of identities to be mutated after construction, so it takes the list lock
@@ -775,7 +775,7 @@ MockNetwork code.
|
-core.testing.MockNetwork |
+node.internal.testing.MockNetwork
A mock node brings up a suite of in-memory services in a fast manner suitable for unit testing.
Components that do IO are either swapped out for mocks, or pointed to a Jimfs in memory filesystem.
@@ -783,7 +783,7 @@ Components that do IO are either swapped out for mocks, or pointed to a
-core.testing.MockNetworkMapCache |
+node.services.network.MockNetworkMapCache
Network map cache with no backing map service.
|
@@ -805,13 +805,13 @@ This is not an interface because it is too lightweight to bother mocking out.
-core.node.subsystems.NetworkCacheError |
+core.node.services.NetworkCacheError
|
-core.node.subsystems.NetworkMapCache |
+core.node.services.NetworkMapCache
A network map contains lists of nodes on the network along with information about their identity keys, services
they provide and host names or IP addresses where they can be connected to. The cache wraps around a map fetched
@@ -821,7 +821,7 @@ with a specified network map service, which it fetches data from and then subscr
|
-core.node.services.NetworkMapService |
+node.services.network.NetworkMapService
A network map contains lists of nodes on the network along with information about their identity keys, services
they provide and host names or IP addresses where they can be connected to. This information is cached locally within
@@ -831,7 +831,7 @@ replace each other based on a serial number present in the change.
|
-core.node.Node |
+node.internal.Node
A Node manages a standalone server that takes part in the P2P network. It creates the services found in ServiceHub,
loads important data off disk and starts listening for connections.
@@ -839,20 +839,20 @@ loads important data off disk and starts listening for connections.
|
-core.node.services.NodeAttachmentService |
+node.services.persistence.NodeAttachmentService
Stores attachments in the specified local directory, which must exist. Doesnt allow new attachments to be uploaded.
|
-core.node.NodeConfiguration |
+node.services.config.NodeConfiguration
|
-core.node.NodeConfigurationFromConfig |
+node.services.config.NodeConfigurationFromConfig
|
@@ -865,7 +865,7 @@ loads important data off disk and starts listening for connections.
|
-core.node.services.NodeInterestRates |
+node.services.clientapi.NodeInterestRates
An interest rates service is an oracle that signs transactions which contain embedded assertions about an interest
rate fix (e.g. LIBOR, EURIBOR ...).
@@ -873,13 +873,13 @@ rate fix (e.g. LIBOR, EURIBOR ...).
|
-core.node.services.NodeMapError |
+node.services.network.NodeMapError
|
-core.node.services.NodeRegistration |
+node.services.network.NodeRegistration
A node registration state in the network map.
|
@@ -894,7 +894,7 @@ add features like checking against other NTP servers to make sure the clock hasn
-core.node.subsystems.NodeWalletService |
+node.services.wallet.NodeWalletService
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
@@ -959,7 +959,7 @@ ledger. The reference is intended to be encrypted so its meaningless to anyone o
|
-core.node.storage.PerFileCheckpointStorage |
+node.services.persistence.PerFileCheckpointStorage
File-based checkpoint storage, storing checkpoints per file.
|
@@ -1003,13 +1003,13 @@ a singleton).
-api.ProtocolClassRef |
+node.api.ProtocolClassRef
|
-api.ProtocolInstanceRef |
+node.api.ProtocolInstanceRef
|
@@ -1024,14 +1024,14 @@ a node crash, how many instances of your protocol there are running and so on.
-api.ProtocolRef |
+node.api.ProtocolRef
Encapsulates the protocol to be instantiated. e.g. TwoPartyTradeProtocol.Buyer.
|
-api.ProtocolRequiringAttention |
+node.api.ProtocolRequiringAttention
Thinking that Instant is OK for short lived protocol deadlines.
|
@@ -1103,7 +1103,7 @@ e.g. LIBOR 6M as of 17 March 2016. Hence it requires a source (name) and a value
-core.node.services.RegulatorService |
+node.services.api.RegulatorService
Placeholder interface for regulator services.
|
@@ -1125,7 +1125,7 @@ all the transactions have been successfully verified and inserted into the local
-api.ResponseFilter |
+node.servlets.ResponseFilter
This adds headers needed for cross site scripting on API clients
|
@@ -1187,7 +1187,7 @@ contained within.
-core.testing.Simulation |
+node.internal.testing.Simulation
Base class for network simulations that are based on the unit test / mock environment.
|
@@ -1209,7 +1209,7 @@ Points at which polynomial pieces connect are known as knots.
-core.messaging.StackSnapshot |
+node.services.statemachine.StackSnapshot
|
@@ -1222,7 +1222,7 @@ Points at which polynomial pieces connect are known as knots.
-core.messaging.StateMachineManager |
+node.services.statemachine.StateMachineManager
A StateMachineManager is responsible for coordination and persistence of multiple ProtocolStateMachine objects.
Each such object represents an instantiation of a (two-party) protocol that has reached a particular point.
@@ -1238,14 +1238,14 @@ transaction defined the state and where in that transaction it was.
|
-api.StatesQuery |
+node.api.StatesQuery
Extremely rudimentary query language which should most likely be replaced with a product
|
-core.node.subsystems.StorageService |
+core.node.services.StorageService
A sketch of an interface to a simple key/value storage system. Intended for persistence of simple blobs like
transactions, serialised protocol state machines and so on. Again, this isnt intended to imply lack of SQL or
@@ -1254,7 +1254,7 @@ anything like that, this interface is only big enough to support the prototyping
|
-core.node.subsystems.StorageServiceImpl |
+node.services.persistence.StorageServiceImpl
|
@@ -1335,7 +1335,7 @@ themselves.
-core.testing.TradeSimulation |
+node.internal.testing.TradeSimulation
Simulates a never ending series of trades that go pair-wise through the banks (e.g. A and B trade with each other,
then B and C trade with each other, then C and A etc).
@@ -1355,7 +1355,7 @@ then B and C trade with each other, then C and A etc).
|
-api.TransactionBuildStep |
+node.api.TransactionBuildStep
Encapsulate a generateXXX method call on a contract.
|
@@ -1469,7 +1469,7 @@ intended as the way things will necessarily be done longer term
-core.node.subsystems.Wallet |
+core.node.services.Wallet
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
@@ -1479,7 +1479,7 @@ about new transactions from our peers and generate new transactions that consume
|
-core.node.subsystems.WalletImpl |
+node.services.wallet.WalletImpl
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
@@ -1489,7 +1489,7 @@ about new transactions from our peers and generate new transactions that consume
|
-core.node.subsystems.WalletService |
+core.node.services.WalletService
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
@@ -1499,7 +1499,7 @@ consumed by someone else first
|
-core.node.services.WireNodeRegistration |
+node.services.network.WireNodeRegistration
A node registration and its signature as a pair.
|
diff --git a/docs/build/html/api/api/-a-p-i-server-impl/-init-.html b/docs/build/html/api/api/-a-p-i-server-impl/-init-.html
index 18200d6124..6690ee2e39 100644
--- a/docs/build/html/api/api/-a-p-i-server-impl/-init-.html
+++ b/docs/build/html/api/api/-a-p-i-server-impl/-init-.html
@@ -7,7 +7,7 @@
api / APIServerImpl / <init>
<init>
-APIServerImpl(node: AbstractNode)
+APIServerImpl(node: AbstractNode)
-abstract fun buildTransaction(type: ContractDefRef, steps: List<TransactionBuildStep>): SerializedBytes<WireTransaction>
-abstract fun commitTransaction(tx: SerializedBytes<WireTransaction>, signatures: List<WithKey>): SecureHash
-abstract fun fetchProtocolsRequiringAttention(query: StatesQuery): Map<StateRef, ProtocolRequiringAttention>
-abstract fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
-abstract fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?>
-abstract fun generateTransactionSignature(tx: SerializedBytes<WireTransaction>): WithKey
-abstract fun invokeProtocolSync(type: ProtocolRef, args: Map<String, Any?>): Any?
-abstract fun provideProtocolResponse(protocol: ProtocolInstanceRef, choice: SecureHash, args: Map<String, Any?>): Unit
-abstract fun queryStates(query: StatesQuery): List<StateRef>
+abstract fun buildTransaction(type: ContractDefRef, steps: List<TransactionBuildStep>): SerializedBytes<WireTransaction>
+abstract fun commitTransaction(tx: SerializedBytes<WireTransaction>, signatures: List<WithKey>): SecureHash
+abstract fun fetchProtocolsRequiringAttention(query: StatesQuery): Map<StateRef, ProtocolRequiringAttention>
+abstract fun fetchStates(states: List<StateRef>): Map<StateRef, ContractState?>
+abstract fun fetchTransactions(txs: List<SecureHash>): Map<SecureHash, SignedTransaction?>
+abstract fun generateTransactionSignature(tx: SerializedBytes<WireTransaction>): WithKey
+abstract fun invokeProtocolSync(type: ProtocolRef, args: Map<String, Any?>): Any?
+abstract fun provideProtocolResponse(protocol: ProtocolInstanceRef, choice: SecureHash, args: Map<String, Any?>): Unit
+abstract fun queryStates(query: StatesQuery): List<StateRef>
abstract fun serverTime(): LocalDateTime