Require notary to be explicitely stated on each transaction

This commit is contained in:
Ross Nicoll
2016-08-04 19:00:17 +01:00
parent a2dff5488f
commit a3d37a4d00
38 changed files with 233 additions and 121 deletions

View File

@ -164,7 +164,7 @@ class WalletMonitorService(net: MessagingService, val smm: StateMachineManager,
// TODO: Make a lightweight protocol that manages this workflow, rather than embedding it directly in the service
private fun initatePayment(req: ClientToServiceCommand.PayCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder()
val builder: TransactionBuilder = TransactionType.General.Builder(null)
// TODO: Have some way of restricting this to states the caller controls
try {
Cash().generateSpend(builder, Amount(req.pennies, req.tokenDef.product), req.owner,
@ -185,7 +185,7 @@ class WalletMonitorService(net: MessagingService, val smm: StateMachineManager,
// TODO: Make a lightweight protocol that manages this workflow, rather than embedding it directly in the service
private fun exitCash(req: ClientToServiceCommand.ExitCash): TransactionBuildResult {
val builder: TransactionBuilder = TransactionType.General.Builder()
val builder: TransactionBuilder = TransactionType.General.Builder(null)
val issuer = PartyAndReference(services.storageService.myLegalIdentity, req.issueRef)
Cash().generateExit(builder, Amount(req.pennies, Issued(issuer, req.currency)),
issuer.party.owningKey, services.walletService.currentWallet.statesOfType<Cash.State>())

View File

@ -39,6 +39,7 @@ import java.util.jar.JarOutputStream
import java.util.zip.ZipEntry
import kotlin.test.assertEquals
import kotlin.test.assertFailsWith
import kotlin.test.assertNotNull
import kotlin.test.assertTrue
/**
@ -407,7 +408,14 @@ class TwoPartyTradeProtocolTests {
bobResult.get()
}
assertTrue(e.cause is TransactionVerificationException)
assertTrue(e.cause!!.cause!!.message!!.contains(expectedMessageSubstring))
assertNotNull(e.cause!!.cause)
assertNotNull(e.cause!!.cause!!.message)
val underlyingMessage = e.cause!!.cause!!.message!!
if (underlyingMessage.contains(expectedMessageSubstring)) {
assertTrue(underlyingMessage.contains(expectedMessageSubstring))
} else {
assertEquals(expectedMessageSubstring, underlyingMessage)
}
}
private fun insertFakeTransactions(
@ -425,8 +433,8 @@ class TwoPartyTradeProtocolTests {
private fun LedgerDSL<TestTransactionDSLInterpreter, TestLedgerDSLInterpreter>.fillUpForBuyer(
withError: Boolean,
owner: PublicKey = BOB_PUBKEY,
issuer: PartyAndReference = DUMMY_CASH_ISSUER): Pair<Wallet, List<WireTransaction>> {
owner: PublicKey = BOB_PUBKEY): Pair<Wallet, 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.
val eb1 = transaction {
@ -435,6 +443,9 @@ class TwoPartyTradeProtocolTests {
output("elbonian money 2") { 1000.DOLLARS.CASH `issued by` issuer `owned by` MEGA_CORP_PUBKEY }
if (!withError)
command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Issue() }
else
// Put a broken command on so at least a signature is created
command(DUMMY_CASH_ISSUER_KEY.public) { Cash.Commands.Move() }
timestamp(TEST_TX_TIME)
if (withError) {
this.fails()

View File

@ -106,7 +106,7 @@ class NodeInterestRatesTest {
val (n1, n2) = net.createTwoNodes()
n2.findService<NodeInterestRates.Service>().oracle.knownFixes = TEST_DATA
val tx = TransactionType.General.Builder()
val tx = TransactionType.General.Builder(null)
val fixOf = NodeInterestRates.parseFixOf("LIBOR 2016-03-16 1M")
val protocol = RatesFixProtocol(tx, n2.info.identity, fixOf, "0.675".bd, "0.1".bd)
LogHelper.setLevel("rates")
@ -122,5 +122,5 @@ class NodeInterestRatesTest {
assertEquals("0.678".bd, fix.value)
}
private fun makeTX() = TransactionType.General.Builder().withItems(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY)
private fun makeTX() = TransactionType.General.Builder(DUMMY_NOTARY).withItems(1000.DOLLARS.CASH `issued by` DUMMY_CASH_ISSUER `owned by` ALICE_PUBKEY `with notary` DUMMY_NOTARY)
}

View File

@ -232,8 +232,8 @@ class NodeSchedulerServiceTest : SingletonSerializeAsToken() {
apply {
val freshKey = services.keyManagementService.freshKey()
val state = TestState(factory.create(TestProtocolLogic::class.java, increment), instant)
val usefulTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
addOutputState(state)
val usefulTX = TransactionType.General.Builder(null).apply {
addOutputState(state, DUMMY_NOTARY)
addCommand(Command(), freshKey.public)
signWith(freshKey)
}.toSignedTransaction()

View File

@ -107,7 +107,7 @@ fun issueState(node: AbstractNode): StateAndRef<*> {
fun issueMultiPartyState(nodeA: AbstractNode, nodeB: AbstractNode): StateAndRef<DummyContract.MultiOwnerState> {
val state = TransactionState(DummyContract.MultiOwnerState(0,
listOf(nodeA.info.identity.owningKey, nodeB.info.identity.owningKey)), DUMMY_NOTARY)
val tx = TransactionType.NotaryChange.Builder().withItems(state)
val tx = TransactionType.NotaryChange.Builder(DUMMY_NOTARY).withItems(state)
tx.signWith(nodeA.storage.myLegalIdentityKey)
tx.signWith(nodeB.storage.myLegalIdentityKey)
tx.signWith(DUMMY_NOTARY_KEY)

View File

@ -39,7 +39,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction with a valid timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder().withItems(inputState)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
tx.setTime(Instant.now(), 30.seconds)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
@ -56,7 +56,7 @@ class NotaryServiceTests {
@Test fun `should sign a unique transaction without a timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder().withItems(inputState)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -72,7 +72,7 @@ class NotaryServiceTests {
@Test fun `should report error for transaction with an invalid timestamp`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder().withItems(inputState)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
tx.setTime(Instant.now().plusSeconds(3600), 30.seconds)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
@ -91,7 +91,7 @@ class NotaryServiceTests {
@Test fun `should report conflict for a duplicate transaction`() {
val stx = run {
val inputState = issueState(clientNode)
val tx = TransactionType.General.Builder().withItems(inputState)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}

View File

@ -39,7 +39,7 @@ class ValidatingNotaryServiceTests {
@Test fun `should report error for invalid transaction dependency`() {
val stx = run {
val inputState = issueInvalidState(clientNode)
val tx = TransactionType.General.Builder().withItems(inputState)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}
@ -59,7 +59,7 @@ class ValidatingNotaryServiceTests {
val inputState = issueState(clientNode)
val command = Command(DummyContract.Commands.Move(), expectedMissingKey)
val tx = TransactionType.General.Builder().withItems(inputState, command)
val tx = TransactionType.General.Builder(DUMMY_NOTARY).withItems(inputState, command)
tx.signWith(clientNode.keyPair!!)
tx.toSignedTransaction(false)
}

View File

@ -71,21 +71,21 @@ class WalletWithCashTest {
fun basics() {
// A tx that sends us money.
val freshKey = services.keyManagementService.freshKey()
val usefulTX = TransactionType.General.Builder().apply {
val usefulTX = TransactionType.General.Builder(null).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), freshKey.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
}.toSignedTransaction()
val myOutput = usefulTX.toLedgerTransaction(services).outRef<Cash.State>(0)
// A tx that spends our money.
val spendTX = TransactionType.General.Builder().apply {
val spendTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
Cash().generateSpend(this, 80.DOLLARS, BOB_PUBKEY, listOf(myOutput))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
// A tx that doesn't send us anything.
val irrelevantTX = TransactionType.General.Builder().apply {
val irrelevantTX = TransactionType.General.Builder(DUMMY_NOTARY).apply {
Cash().generateIssue(this, 100.DOLLARS `issued by` MEGA_CORP.ref(1), BOB_KEY.public, DUMMY_NOTARY)
signWith(MEGA_CORP_KEY)
signWith(DUMMY_NOTARY_KEY)
@ -112,6 +112,7 @@ class WalletWithCashTest {
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearState(thread = thread, participants = listOf(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
wallet.notify(dummyIssue.tx)
@ -121,6 +122,7 @@ class WalletWithCashTest {
val dummyIssue2 = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearState(thread = thread, participants = listOf(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
assertThatThrownBy {
@ -139,6 +141,7 @@ class WalletWithCashTest {
val dummyIssue = TransactionType.General.Builder(notary = DUMMY_NOTARY).apply {
addOutputState(DummyLinearState(thread = thread, participants = listOf(freshKey.public)))
signWith(freshKey)
signWith(DUMMY_NOTARY_KEY)
}.toSignedTransaction()
wallet.notify(dummyIssue.tx)

View File

@ -34,7 +34,7 @@ class DataVendingServiceTests {
network.runNetwork()
// Generate an issuance transaction
val ptx = TransactionType.General.Builder()
val ptx = TransactionType.General.Builder(null)
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// Complete the cash transaction, and then manually relay it
@ -66,7 +66,7 @@ class DataVendingServiceTests {
network.runNetwork()
// Generate an issuance transaction
val ptx = TransactionType.General.Builder()
val ptx = TransactionType.General.Builder(DUMMY_NOTARY)
Cash().generateIssue(ptx, Amount(100, Issued(deposit, USD)), beneficiary, DUMMY_NOTARY)
// The transaction tries issuing MEGA_CORP cash, but we aren't the issuer, so it's invalid