Updated based on feedback to check that the encumbered state does not refer to itself as the encumbrance.

This commit is contained in:
jamescarlyle 2016-08-19 17:45:25 +01:00
parent fec2134555
commit 6ba301b6b8
2 changed files with 40 additions and 1 deletions

View File

@ -81,11 +81,21 @@ sealed class TransactionType {
// Validate that all encumbrances exist within the set of input states.
tx.inputs.filter { it.state.data.encumbrance != null }.forEach {
encumberedInput ->
if (tx.inputs.none { it.ref.txhash == encumberedInput.ref.txhash && it.ref.index == encumberedInput.state.data.encumbrance }) {
if (tx.inputs.none { it.ref.txhash == encumberedInput.ref.txhash &&
it.ref.index == encumberedInput.state.data.encumbrance }) {
throw TransactionVerificationException.TransactionMissingEncumbranceException(tx)
}
}
// Check that an encumbered state does not refer to itself as the encumbrance, and that the number of outputs
// can contain the encumbrance.
tx.outputs.forEachIndexed { i, it ->
if (it.data.encumbrance != null) {
if (it.data.encumbrance == i || it.data.encumbrance!! >= tx.outputs.size) {
throw TransactionVerificationException.TransactionMissingEncumbranceException(tx)
}
}
}
}
override fun getRequiredSigners(tx: LedgerTransaction) = tx.commands.flatMap { it.signers }.toSet()

View File

@ -67,6 +67,35 @@ class TransactionEncumbranceTests {
this.verifies()
}
}
// An encumbered state must not be encumbered by itself.
assertFailsWith(TransactionVerificationException.TransactionMissingEncumbranceException::class) {
transaction {
input { unencumberedState }
input { unencumberedState }
output { unencumberedState }
// The encumbered state refers to an encumbrance in position 1, so what follows is wrong.
output { encumberedState }
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
this.verifies()
}
}
// An encumbered state must not reference an index greater than the size of the output states.
assertFailsWith(TransactionVerificationException.TransactionMissingEncumbranceException::class) {
transaction {
input { unencumberedState }
input { unencumberedState }
output { unencumberedState }
// The encumbered state refers to an encumbrance in position 1, so what follows is wrong.
output { encumberedState }
command(DUMMY_PUBKEY_1) { Cash.Commands.Move() }
this.verifies()
}
}
}
@Test
fun testEncumbranceEffects() {
// A transaction containing an input state that is encumbered must fail if the encumbrance is not in the correct position.
assertFailsWith(TransactionVerificationException.TransactionMissingEncumbranceException::class) {
ledger {