Skip to content

Commit 689002a

Browse files
authored
Merge pull request #5480 from IntersectMBO/td/skip-isvalid-in-tx-serialization
Skip `isValid` flag in transaction (de)/serialization
2 parents 7aaa7e1 + 7fd5a50 commit 689002a

File tree

7 files changed

+128
-27
lines changed

7 files changed

+128
-27
lines changed

eras/dijkstra/impl/cddl/data/dijkstra.cddl

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,10 @@ block =
1515

1616

1717
transaction =
18-
[transaction_body, transaction_witness_set, bool, auxiliary_data/ nil]
18+
[ transaction_body, transaction_witness_set, true, auxiliary_data/ nil
19+
// transaction_body, transaction_witness_set, auxiliary_data/ nil
20+
]
21+
1922

2023
kes_signature = bytes .size 448
2124

eras/dijkstra/impl/cddl/lib/Cardano/Ledger/Dijkstra/HuddleSpec.hs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,12 @@ instance HuddleRule "transaction" DijkstraEra where
672672
=:= arr
673673
[ a $ huddleRule @"transaction_body" p
674674
, a $ huddleRule @"transaction_witness_set" p
675-
, a VBool
675+
, a $ (bool True)
676+
, a (huddleRule @"auxiliary_data" p / VNil)
677+
]
678+
/ arr
679+
[ a $ huddleRule @"transaction_body" p
680+
, a $ huddleRule @"transaction_witness_set" p
676681
, a (huddleRule @"auxiliary_data" p / VNil)
677682
]
678683

eras/dijkstra/impl/src/Cardano/Ledger/Dijkstra/Tx.hs

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import Cardano.Ledger.Binary (
3636
EncCBOR (..),
3737
Encoding,
3838
ToCBOR (..),
39+
decodeListLen,
3940
decodeNullStrictMaybe,
4041
encodeListLen,
4142
encodeNullStrictMaybe,
@@ -119,13 +120,35 @@ instance EraTx era => EncCBOR (DijkstraTx l era) where
119120

120121
instance (EraTx era, Typeable l) => DecCBOR (Annotator (DijkstraTx l era)) where
121122
decCBOR = withSTxBothLevels @l $ \case
122-
STopTx ->
123-
decode $
124-
Ann (RecD DijkstraTx)
125-
<*! From
126-
<*! From
127-
<*! Ann From
128-
<*! D (sequence <$> decodeNullStrictMaybe decCBOR)
123+
STopTx -> do
124+
decodeListLen >>= \case
125+
4 -> do
126+
bodyAnn <- decCBOR
127+
witsAnn <- decCBOR
128+
isValid <-
129+
decCBOR
130+
>>= \case
131+
True -> pure (IsValid True)
132+
False -> fail "value `false` not allowed for `isValid`"
133+
auxAnn <- decodeNullStrictMaybe decCBOR
134+
pure $
135+
DijkstraTx
136+
<$> bodyAnn
137+
<*> witsAnn
138+
<*> pure isValid
139+
<*> sequence auxAnn
140+
3 -> do
141+
bodyAnn <- decCBOR
142+
witsAnn <- decCBOR
143+
auxAnn <- decodeNullStrictMaybe decCBOR
144+
pure $
145+
DijkstraTx
146+
<$> bodyAnn
147+
<*> witsAnn
148+
<*> pure (IsValid True)
149+
<*> sequence auxAnn
150+
n ->
151+
fail $ "Unexpected list length: " <> show n <> ". Expected: 4 or 3."
129152
SSubTx ->
130153
decode $
131154
Ann (RecD DijkstraSubTx)
@@ -323,7 +346,7 @@ toCBORForMempoolSubmission = \case
323346
Rec DijkstraTx
324347
!> To dtBody
325348
!> To dtWits
326-
!> To dtIsValid
349+
!> OmitC dtIsValid
327350
!> E (encodeNullStrictMaybe encCBOR) dtAuxData
328351
DijkstraSubTx {dstBody, dstWits, dstAuxData} ->
329352
encode $

eras/dijkstra/impl/testlib/Test/Cardano/Ledger/Dijkstra/Arbitrary.hs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,9 @@ sizedDijkstraNativeScript n =
131131
instance (Arbitrary (TxBody l DijkstraEra), Typeable l) => Arbitrary (Tx l DijkstraEra) where
132132
arbitrary =
133133
fmap MkDijkstraTx . withSTxBothLevels @l $ \case
134-
STopTx -> DijkstraTx <$> arbitrary <*> arbitrary <*> arbitrary <*> arbitrary
134+
-- Per CIP-0167, Dijkstra transactions should always have isValid = True
135+
-- The isValid flag is omitted in serialization and defaults to True
136+
STopTx -> DijkstraTx <$> arbitrary <*> arbitrary <*> pure (IsValid True) <*> arbitrary
135137
SSubTx -> DijkstraSubTx <$> arbitrary <*> arbitrary <*> arbitrary
136138

137139
instance Era era => Arbitrary (DijkstraTxCert era) where

eras/dijkstra/impl/testlib/Test/Cardano/Ledger/Dijkstra/Binary/Annotator.hs

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ module Test.Cardano.Ledger.Dijkstra.Binary.Annotator (
1717

1818
import Cardano.Ledger.Address (Withdrawals (..))
1919
import Cardano.Ledger.Allegra.Scripts (invalidBeforeL, invalidHereAfterL)
20+
import Cardano.Ledger.Alonzo.Tx (IsValid (..))
2021
import Cardano.Ledger.BaseTypes
2122
import Cardano.Ledger.Binary
2223
import Cardano.Ledger.Binary.Coders
@@ -165,12 +166,24 @@ instance Typeable l => DecCBOR (DijkstraTx l DijkstraEra) where
165166
decCBOR =
166167
withSTxBothLevels @l $ \case
167168
STopTx ->
168-
decode $
169-
RecD DijkstraTx
170-
<! From
171-
<! From
172-
<! From
173-
<! D (decodeNullStrictMaybe decCBOR)
169+
decodeListLen >>= \case
170+
4 -> do
171+
body <- decCBOR
172+
wits <- decCBOR
173+
isValid <-
174+
decCBOR
175+
>>= \case
176+
True -> pure (IsValid True)
177+
False -> fail "value `false` not allowed for `isValid`"
178+
aux <- decodeNullStrictMaybe decCBOR
179+
pure $ DijkstraTx body wits isValid aux
180+
3 -> do
181+
DijkstraTx
182+
<$> decCBOR
183+
<*> decCBOR
184+
<*> pure (IsValid True)
185+
<*> decodeNullStrictMaybe decCBOR
186+
n -> fail $ "Unexpected list length: " <> show n <> ". Expected: 4 or 3."
174187
SSubTx ->
175188
decode $
176189
RecD DijkstraSubTx

eras/dijkstra/impl/testlib/Test/Cardano/Ledger/Dijkstra/Binary/Golden.hs

Lines changed: 61 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,7 @@ import Cardano.Ledger.BaseTypes (Version)
1818
import Cardano.Ledger.Binary (Annotator, DecoderError (..), DeserialiseFailure (..), Tokens (..))
1919
import qualified Cardano.Ledger.Binary as Binary
2020
import Cardano.Ledger.Coin (Coin (..))
21-
import Cardano.Ledger.Dijkstra.Core (
22-
EraTx (..),
23-
EraTxBody (..),
24-
EraTxOut (..),
25-
EraTxWits (..),
26-
TxLevel (..),
27-
eraProtVerLow,
28-
)
21+
import Cardano.Ledger.Dijkstra.Core
2922
import Cardano.Ledger.Dijkstra.TxBody
3023
import Cardano.Ledger.Plutus (SLanguage (..))
3124
import Cardano.Ledger.TxIn (TxIn (..))
@@ -55,8 +48,11 @@ spec = describe "Golden" . forEachEraVersion @era $ \version -> do
5548
goldenDuplicatePlutusScriptsDisallowed @era version SPlutusV2
5649
goldenDuplicatePlutusScriptsDisallowed @era version SPlutusV3
5750
goldenDuplicatePlutusDataDisallowed @era version
58-
goldenSubTransactions @era
5951
goldenEmptyFields @era version
52+
describe "Subtransactions" $ do
53+
goldenSubTransactions @era
54+
describe "IsValid flag" $ do
55+
goldenIsValidFlag @era
6056

6157
goldenEmptyFields :: forall era. DijkstraEraTest era => Version -> Spec
6258
goldenEmptyFields version =
@@ -279,3 +275,59 @@ goldenSubTransactions = do
279275
, E (TkMapLen 0)
280276
, E TkNull
281277
]
278+
279+
goldenIsValidFlag :: forall era. DijkstraEraTest era => Spec
280+
goldenIsValidFlag = do
281+
it "Deserialize transactions with missing `isValid` flag" $
282+
expectDecoderResultOn @(Tx TopTx era)
283+
version
284+
txWithoutFlagEnc
285+
basicValidTx
286+
id
287+
it "Deserialize transactions with `isValid` flag set to true" $
288+
expectDecoderResultOn @(Tx TopTx era)
289+
version
290+
txWithFlagTrueEnc
291+
basicValidTx
292+
id
293+
it "Fail to deserialize transactions with `isValid` flag set to false" $
294+
expectDecoderFailureAnn @(Tx TopTx era)
295+
version
296+
txWithFlagFalseEnc
297+
( DecoderErrorDeserialiseFailure
298+
"Annotator (Tx TopTx DijkstraEra)"
299+
(DeserialiseFailure 13 "value `false` not allowed for `isValid`")
300+
)
301+
where
302+
version = eraProtVerLow @era
303+
basicValidTx = mkBasicTx @era @TopTx (mkBasicTxBody @era @TopTx) & isValidTxL .~ IsValid True
304+
txWithoutFlagEnc =
305+
mconcat
306+
[ E $ TkListLen 3
307+
, txBodyEnc
308+
, E (TkMapLen 0)
309+
, E TkNull
310+
]
311+
txWithFlagTrueEnc =
312+
mconcat
313+
[ E $ TkListLen 4
314+
, txBodyEnc
315+
, E (TkMapLen 0)
316+
, E (TkBool True)
317+
, E TkNull
318+
]
319+
txWithFlagFalseEnc =
320+
mconcat
321+
[ E $ TkListLen 4
322+
, txBodyEnc
323+
, E (TkMapLen 0)
324+
, E (TkBool False)
325+
, E TkNull
326+
]
327+
txBodyEnc =
328+
mconcat
329+
[ E $ TkMapLen 3
330+
, Em [E @Int 0, Ev version $ Set.empty @TxIn]
331+
, Em [E @Int 1, Ev version $ [] @(TxOut era)]
332+
, Em [E @Int 2, E $ Coin 0]
333+
]

libs/cardano-ledger-api/test/Tests.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,10 @@ apiSpec =
4949
Upgrade.spec @AlonzoEra (BinaryUpgradeOpts False False)
5050
Upgrade.spec @BabbageEra def
5151
Upgrade.spec @ConwayEra def
52-
Upgrade.spec @DijkstraEra def
52+
-- Transactions with isValid=False cannot be binary-upgraded due to CIP-0167,
53+
-- which removes the isValid flag from mempool transactions. They are still
54+
-- upgradeable via the translateEra method at the hard fork boundary.
55+
Upgrade.spec @DijkstraEra (BinaryUpgradeOpts True False)
5356

5457
main :: IO ()
5558
main = ledgerTestMain apiSpec

0 commit comments

Comments
 (0)