Skip to content

Commit

Permalink
Merge #3346
Browse files Browse the repository at this point in the history
3346: Extend hard-coded test blockchain to test collateral inputs and outputs. r=jonathanknowles a=jonathanknowles

## Issue Number

ADP-1814

## Summary

This PR extends the hard-coded test blockchain in `ModelSpec` (an excerpt of the mainnet blockchain).

It appends a pair of transactions to the end: (and ensures that all tests pass)

- Transaction `t0`:
  - marked as **_failing_** script validation
  - specifies a single collateral input `cinp_0`
  - specifies a single collateral output `cout_0`
  
- Transaction `t1`:
  - marked as **_passing_** script validation
  - specifies a single ordinary input that refers to `cout_0` of `t0`

## Details

The first commit in this PR is marked with `[FAIL]`, as it causes a test failure in "_applyBlock matches the basic model from the specification_".

The cause of this failure is that the following **_test_** functions were not updated to account for script validation:
- `ModelSpec.updateUTxO`
- `ModelSpec.txOutsOurs`

Subsequent commits adjust these functions to correctly account for script validation. The first commit to result in a passing test suite is marked with `[PASS]`.

Co-authored-by: Jonathan Knowles <[email protected]>
  • Loading branch information
iohk-bors[bot] and jonathanknowles authored Jun 21, 2022
2 parents c3f5038 + 98b547b commit d7cfa89
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 4 deletions.
2 changes: 1 addition & 1 deletion lib/core/src/Cardano/Wallet/Primitive/Types/Tx.hs
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ instance Buildable TxScriptValidity where
build TxScriptInvalid = "invalid"

txIns :: Set Tx -> Set TxIn
txIns = foldMap (Set.fromList . inputs)
txIns = foldMap (\tx -> Set.fromList (inputs tx <> collateralInputs tx))

inputs :: Tx -> [TxIn]
inputs = map fst . resolvedInputs
Expand Down
113 changes: 110 additions & 3 deletions lib/core/test/unit/Cardano/Wallet/Primitive/ModelSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -986,7 +986,15 @@ updateUTxO !b utxo = do
let txs = Set.fromList $ transactions b
utxo' <- (foldMap utxoFromTx txs `restrictedTo`) . Set.map snd
<$> state (txOutsOurs txs)
return $ (utxo <> utxo') `excluding` txIns txs
return $
(utxo <> utxo') `excluding` foldMap (Set.fromList . inputsToSpend) txs
where
inputsToSpend :: Tx -> [TxIn]
inputsToSpend tx
| txScriptInvalid tx =
collateralInputs tx
| otherwise =
inputs tx

-- | Return all transaction outputs that are ours. This plays well within a
-- 'State' monad.
Expand All @@ -1003,8 +1011,8 @@ txOutsOurs
-> s
-> (Set (Tx, TxOut), s)
txOutsOurs txs =
runState $ Set.fromList <$>
forMaybe (foldMap (\tx -> zip (repeat tx) (outputs tx)) txs) pick
runState $ Set.fromList <$> forMaybe
(foldMap (\tx -> zip (repeat tx) (outputsToCreate tx)) txs) pick
where
pick :: (Tx, TxOut) -> State s (Maybe (Tx, TxOut))
pick (tx, out) = do
Expand All @@ -1015,6 +1023,13 @@ txOutsOurs txs =
forMaybe :: Monad m => [a] -> (a -> m (Maybe b)) -> m [b]
forMaybe xs = fmap catMaybes . for xs

outputsToCreate :: Tx -> [TxOut]
outputsToCreate tx
| txScriptInvalid tx =
F.toList (collateralOutput tx)
| otherwise =
outputs tx

{-------------------------------------------------------------------------------
Test Data
Expand Down Expand Up @@ -1926,6 +1941,98 @@ blockchain =
]
, delegations = []
}

-- After this point, all blocks and transactions are constructed by hand,
-- in order to simulate various interesting scenarios:

, Block
{ header = BlockHeader
{ slotNo = slot 14 20
, blockHeight = Quantity 302378
, headerHash = Hash "unused"
, parentHeaderHash = Just $ Hash "unused"
}
, transactions =
-- This transaction is marked as having an invalid script.
-- It spends a single collateral input and creates a single
-- collateral output:
[ Tx
{ txId = Hash "tx-create-collateral-output"
, fee = Just (Coin 1)
, resolvedInputs =
[ ( TxIn
{ inputId = Hash "9c6fed8fef3b296d4dee6e62ca72b180bf0ed1c13eb5f0445099b2a146235e77"
, inputIx = 0
}
, Coin 3823755953610
)
]
, resolvedCollateralInputs =
[ ( TxIn
{ inputId = Hash "9c6fed8fef3b296d4dee6e62ca72b180bf0ed1c13eb5f0445099b2a146235e77"
, inputIx = 1
}
, Coin 19999800000
)
]
, outputs =
[ TxOut
{ address = Address "\130\216\CANXB\131X\FS\147\ACKn\246.n\DLE\233Y\166)\207c\v\248\183\235\212\EOTV\243h\192\190T\150'\196\161\SOHX\RSX\FS\202>U<\156c\197&\DC3S\235C\198\245\163\204=\214fa\201\t\205\248\204\226r%\NUL\SUB\174\187\&7\t"
, tokens = coinToBundle (3823755953610 - 1)
}
]
, collateralOutput = Just
TxOut
{ address = Address "\130\216\CANXB\131X\FS\147\ACKn\246.n\DLE\233Y\166)\207c\v\248\183\235\212\EOTV\243h\192\190T\150'\196\161\SOHX\RSX\FS\202>U<\156c\197&\DC3S\235C\198\245\163\204=\214fa\201\t\205\248\204\226r%\NUL\SUB\174\187\&7\t"
, tokens = coinToBundle (19999800000 - 1)
}
, withdrawals = mempty
, metadata = Nothing
, scriptValidity = Just TxScriptInvalid
}
]
, delegations = []
}

, Block
{ header = BlockHeader
{ slotNo = slot 14 21
, blockHeight = Quantity 302379
, headerHash = Hash "unused"
, parentHeaderHash = Just $ Hash "unused"
}
, transactions =
-- This transaction spends a single collateral output that was
-- created in the previous transaction:
[ Tx
{ txId = Hash "tx-spend-collateral-output"
, fee = Just (Coin 1)
, resolvedInputs =
[ ( TxIn
{ inputId = Hash "tx-create-collateral-output"
-- The previous transaction defined exactly one
-- ordinary output, so we use 1 as the index of
-- the collateral output:
, inputIx = 1
}
, Coin (19999800000 - 1)
)
]
, resolvedCollateralInputs = []
, outputs =
[ TxOut
{ address = Address "\130\216\CANXB\131X\FS\147\ACKn\246.n\DLE\233Y\166)\207c\v\248\183\235\212\EOTV\243h\192\190T\150'\196\161\SOHX\RSX\FS\202>U<\156c\197&\DC3S\235C\198\245\163\204=\214fa\201\t\205\248\204\226r%\NUL\SUB\174\187\&7\t"
, tokens = coinToBundle (19999800000 - 2)
}
]
, collateralOutput = Nothing
, withdrawals = mempty
, metadata = Nothing
, scriptValidity = Just TxScriptValid
}
]
, delegations = []
}
]
where
slot e s = SlotNo $ flatSlot (EpochLength 21600) (SlotId e s)
Expand Down

0 comments on commit d7cfa89

Please sign in to comment.