Skip to content

Commit f7abd5b

Browse files
committed
Flip TxIx serialization to big endian
1 parent 2e0ce6f commit f7abd5b

File tree

15 files changed

+90
-34
lines changed

15 files changed

+90
-34
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano/CanHardFork.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,7 @@ translateLedgerStateShelleyToAllegraWrapper =
466466
LedgerTables
467467
. DiffMK
468468
. Diff.fromMapDeletes
469+
. coerceTxInMapKeys
469470
. Map.map SL.upgradeTxOut
470471
$ avvms
471472

@@ -478,6 +479,7 @@ translateLedgerStateShelleyToAllegraWrapper =
478479
. withLedgerTables ls
479480
. LedgerTables
480481
. ValuesMK
482+
. coerceTxInMapKeys
481483
$ avvms
482484

483485
resultingState =

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano/Ledger.hs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ import Cardano.Ledger.Binary.Decoding hiding (Decoder)
2828
import Cardano.Ledger.Binary.Encoding hiding (Encoding)
2929
import qualified Cardano.Ledger.Conway.State as SL
3030
import Cardano.Ledger.Core (Era, eraDecoder, eraProtVerLow)
31-
import qualified Cardano.Ledger.Shelley.API as SL
3231
import Cardano.Ledger.Shelley.LedgerState as SL
3332
( esLStateL
3433
, lsCertStateL
@@ -57,7 +56,8 @@ import Ouroboros.Consensus.Ledger.Tables
5756
import Ouroboros.Consensus.Protocol.Praos (Praos)
5857
import Ouroboros.Consensus.Protocol.TPraos (TPraos)
5958
import Ouroboros.Consensus.Shelley.Ledger
60-
( IsShelleyBlock
59+
( BigEndianTxIn
60+
, IsShelleyBlock
6161
, ShelleyBlock
6262
, ShelleyCompatible
6363
, shelleyLedgerState
@@ -70,7 +70,7 @@ instance
7070
HasCanonicalTxIn (CardanoEras c)
7171
where
7272
newtype CanonicalTxIn (CardanoEras c) = CardanoTxIn
73-
{ getCardanoTxIn :: SL.TxIn
73+
{ getCardanoTxIn :: BigEndianTxIn
7474
}
7575
deriving stock (Show, Eq, Ord)
7676
deriving newtype NoThunks

ouroboros-consensus-cardano/src/ouroboros-consensus-cardano/Ouroboros/Consensus/Cardano/QueryHF.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
module Ouroboros.Consensus.Cardano.QueryHF () where
2121

22+
import Data.Coerce
2223
import Data.Functor.Product
2324
import Data.SOP.BasicFunctors
2425
import Data.SOP.Constraint
@@ -98,14 +99,14 @@ instance CardanoHardForkConstraints c => BlockSupportsHFLedgerQuery (CardanoEras
9899
answerShelleyLookupQueries
99100
(injectLedgerTables idx)
100101
(ejectHardForkTxOut idx)
101-
(ejectCanonicalTxIn idx)
102+
(coerce . ejectCanonicalTxIn idx)
102103
)
103104
answerBlockQueryHFTraverse =
104105
answerCardanoQueryHF
105106
( \idx ->
106107
answerShelleyTraversingQueries
107108
(ejectHardForkTxOut idx)
108-
(ejectCanonicalTxIn idx)
109+
(coerce . ejectCanonicalTxIn idx)
109110
(queryLedgerGetTraversingFilter idx)
110111
)
111112

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Ledger.hs

Lines changed: 50 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,13 @@ module Ouroboros.Consensus.Shelley.Ledger.Ledger
5454

5555
-- * Low-level UTxO manipulations
5656
, slUtxoL
57+
, BigEndianTxIn (..)
58+
, coerceTxInSet
59+
, coerceTxInMapKeys
5760
) where
5861

5962
import qualified Cardano.Ledger.BHeaderView as SL (BHeaderView)
60-
import qualified Cardano.Ledger.BaseTypes as SL (epochInfoPure)
63+
import qualified Cardano.Ledger.BaseTypes as SL (TxIx (..), epochInfoPure)
6164
import Cardano.Ledger.BaseTypes.NonZero (unNonZero)
6265
import Cardano.Ledger.Binary.Decoding
6366
( decShareCBOR
@@ -97,9 +100,11 @@ import Control.Arrow (left, second)
97100
import qualified Control.Exception as Exception
98101
import Control.Monad.Except
99102
import qualified Control.State.Transition.Extended as STS
100-
import Data.Coerce (coerce)
103+
import Data.Coerce
101104
import Data.Functor.Identity
105+
import Data.Map.Strict (Map)
102106
import Data.MemPack
107+
import Data.Set (Set)
103108
import qualified Data.Text as T
104109
import qualified Data.Text as Text
105110
import Data.Word
@@ -135,7 +140,9 @@ import Ouroboros.Consensus.Util.CBOR
135140
, encodeWithOrigin
136141
)
137142
import Ouroboros.Consensus.Util.IndexedMemPack
143+
import Ouroboros.Consensus.Util.RedundantConstraints (keepRedundantConstraint)
138144
import Ouroboros.Consensus.Util.Versioned
145+
import Unsafe.Coerce
139146

140147
{-------------------------------------------------------------------------------
141148
Config
@@ -317,7 +324,32 @@ shelleyLedgerTipPoint = shelleyTipToPoint . shelleyLedgerTip
317324

318325
instance ShelleyCompatible proto era => UpdateLedger (ShelleyBlock proto era)
319326

320-
type instance TxIn (LedgerState (ShelleyBlock proto era)) = SL.TxIn
327+
-- | The only purpose of this type is to modify the MemPack instance to use big
328+
-- endian serialization. This is necessary to ensure streaming functions of the
329+
-- UTxO set preserve the order of the entries, as otherwise we would get
330+
-- different sortings if sorting via the Serialized form and the Haskell Ord
331+
-- instance.
332+
newtype BigEndianTxIn = BigEndianTxIn {getOriginalTxIn :: SL.TxIn}
333+
deriving newtype (Eq, Show, Ord, NoThunks)
334+
335+
newtype BigEndianTxIx = BigEndianTxIx {getOriginalTxIx :: SL.TxIx}
336+
337+
instance MemPack BigEndianTxIx where
338+
typeName = "BigEndianTxIx"
339+
packedByteCount = packedByteCount . getOriginalTxIx
340+
packM (BigEndianTxIx (SL.TxIx w)) = packM (byteSwap16 w)
341+
unpackM = BigEndianTxIx . SL.TxIx . byteSwap16 <$> unpackM
342+
343+
instance MemPack BigEndianTxIn where
344+
typeName = "BigEndianTxIn"
345+
packedByteCount = packedByteCount . getOriginalTxIn
346+
packM (BigEndianTxIn (SL.TxIn txid txix)) = do
347+
packM txid
348+
packM (BigEndianTxIx txix)
349+
unpackM = do
350+
BigEndianTxIn <$> (SL.TxIn <$> unpackM <*> (getOriginalTxIx <$> unpackM))
351+
352+
type instance TxIn (LedgerState (ShelleyBlock proto era)) = BigEndianTxIn
321353
type instance TxOut (LedgerState (ShelleyBlock proto era)) = Core.TxOut era
322354

323355
instance
@@ -397,7 +429,7 @@ instance
397429
, shelleyLedgerTables = emptyLedgerTables
398430
}
399431
where
400-
(_, shelleyLedgerState') = shelleyLedgerState `slUtxoL` SL.UTxO m
432+
(_, shelleyLedgerState') = shelleyLedgerState `slUtxoL` SL.UTxO (coerceTxInMapKeys m)
401433
ShelleyLedgerState
402434
{ shelleyLedgerTip
403435
, shelleyLedgerState
@@ -409,7 +441,7 @@ instance
409441
{ shelleyLedgerTip = shelleyLedgerTip
410442
, shelleyLedgerState = shelleyLedgerState'
411443
, shelleyLedgerTransition = shelleyLedgerTransition
412-
, shelleyLedgerTables = LedgerTables (ValuesMK (SL.unUTxO tbs))
444+
, shelleyLedgerTables = LedgerTables (ValuesMK (coerceTxInMapKeys $ SL.unUTxO tbs))
413445
}
414446
where
415447
(tbs, shelleyLedgerState') = shelleyLedgerState `slUtxoL` mempty
@@ -419,6 +451,16 @@ instance
419451
, shelleyLedgerTransition
420452
} = st
421453

454+
coerceTxInMapKeys :: forall k1 k2 v. Coercible k1 k2 => Map k1 v -> Map k2 v
455+
coerceTxInMapKeys = unsafeCoerce
456+
where
457+
_ = keepRedundantConstraint (Proxy @(Coercible k1 k2))
458+
459+
coerceTxInSet :: forall k1 k2. Coercible k1 k2 => Set k1 -> Set k2
460+
coerceTxInSet = unsafeCoerce
461+
where
462+
_ = keepRedundantConstraint (Proxy @(Coercible k1 k2))
463+
422464
instance
423465
ShelleyBasedEra era =>
424466
CanStowLedgerTables (Ticked (LedgerState (ShelleyBlock proto era)))
@@ -432,7 +474,7 @@ instance
432474
}
433475
where
434476
(_, tickedShelleyLedgerState') =
435-
tickedShelleyLedgerState `slUtxoL` SL.UTxO tbs
477+
tickedShelleyLedgerState `slUtxoL` SL.UTxO (coerceTxInMapKeys tbs)
436478
TickedShelleyLedgerState
437479
{ untickedShelleyLedgerTip
438480
, tickedShelleyLedgerTransition
@@ -445,7 +487,7 @@ instance
445487
{ untickedShelleyLedgerTip = untickedShelleyLedgerTip
446488
, tickedShelleyLedgerTransition = tickedShelleyLedgerTransition
447489
, tickedShelleyLedgerState = tickedShelleyLedgerState'
448-
, tickedShelleyLedgerTables = LedgerTables (ValuesMK (SL.unUTxO tbs))
490+
, tickedShelleyLedgerTables = LedgerTables (ValuesMK (coerceTxInMapKeys (SL.unUTxO tbs)))
449491
}
450492
where
451493
(tbs, tickedShelleyLedgerState') = tickedShelleyLedgerState `slUtxoL` mempty
@@ -583,6 +625,7 @@ instance
583625
getBlockKeySets =
584626
LedgerTables
585627
. KeysMK
628+
. coerceTxInSet
586629
. Core.neededTxInsForBlock
587630
. shelleyBlockRaw
588631

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Mempool.hs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,10 @@ import Ouroboros.Consensus.Ledger.Tables.Utils
9898
import Ouroboros.Consensus.Shelley.Eras
9999
import Ouroboros.Consensus.Shelley.Ledger.Block
100100
import Ouroboros.Consensus.Shelley.Ledger.Ledger
101-
( ShelleyLedgerConfig (shelleyLedgerGlobals)
101+
( BigEndianTxIn (..)
102+
, ShelleyLedgerConfig (shelleyLedgerGlobals)
102103
, Ticked (TickedShelleyLedgerState, tickedShelleyLedgerState)
104+
, coerceTxInSet
103105
, getPParams
104106
)
105107
import Ouroboros.Consensus.Shelley.Protocol.Abstract (ProtoCrypto)
@@ -177,8 +179,9 @@ instance
177179

178180
getTransactionKeySets (ShelleyTx _ tx) =
179181
LedgerTables $
180-
KeysMK
181-
(tx ^. bodyTxL . allInputsTxBodyF)
182+
KeysMK $
183+
coerceTxInSet
184+
(tx ^. bodyTxL . allInputsTxBodyF)
182185

183186
mkShelleyTx :: forall era proto. ShelleyBasedEra era => Tx era -> GenTx (ShelleyBlock proto era)
184187
mkShelleyTx tx = ShelleyTx (txIdTx tx) tx

ouroboros-consensus-cardano/src/shelley/Ouroboros/Consensus/Shelley/Ledger/Query.hs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ import qualified Codec.CBOR.Encoding as CBOR
6767
import Codec.Serialise (decode, encode)
6868
import Control.DeepSeq (NFData)
6969
import Data.Bifunctor (second)
70+
import Data.Coerce
7071
import Data.Map.Strict (Map)
7172
import qualified Data.Map.Strict as Map
7273
import Data.MemPack
@@ -554,9 +555,9 @@ instance
554555
hst = headerState ext
555556
st = shelleyLedgerState lst
556557

557-
answerBlockQueryLookup = answerShelleyLookupQueries id id id
558+
answerBlockQueryLookup = answerShelleyLookupQueries id id coerce
558559

559-
answerBlockQueryTraverse = answerShelleyTraversingQueries id id shelleyQFTraverseTablesPredicate
560+
answerBlockQueryTraverse = answerShelleyTraversingQueries id coerce shelleyQFTraverseTablesPredicate
560561

561562
-- \| Is the given query supported by the given 'ShelleyNodeToClientVersion'?
562563
blockQueryIsSupportedOnVersion = \case
@@ -1242,7 +1243,7 @@ answerShelleyLookupQueries injTables ejTxOut ejTxIn cfg q forker =
12421243
LedgerTables (ValuesMK values) <-
12431244
LedgerDB.roforkerReadTables
12441245
forker
1245-
(castLedgerTables $ injTables (LedgerTables $ KeysMK txins))
1246+
(castLedgerTables $ injTables (LedgerTables $ KeysMK $ coerceTxInSet txins))
12461247
pure $
12471248
SL.UTxO $
12481249
Map.mapKeys ejTxIn $

0 commit comments

Comments
 (0)