Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix ValueNotConservedUTxO serialization #1955

Merged
merged 2 commits into from
Oct 30, 2020

Conversation

JaredCorduan
Copy link
Contributor

The ValueNotConservedUTxO predicate failure contains two values of type Coin (in the Shelley era, but Core.Value in general). Though the Coin values in the ledger state are always within the proper bounds (ie Word64), the failure could produce values outside of this range. This caused a serialization error for ValueNotConservedUTxO, since we do not allow the serialization of coins out of the Word64 range.

For the Coin type, we already had a wrapper DeltaCoin which can be used when we want to intentionally serialize any Coin. This is now generalized to a Torsor type class, which ValueNotConservedUTxO now uses (I'm happy to have help with the name...).

!(Core.Value era) -- the Coin consumed by this transaction
!(Core.Value era) -- the Coin produced by this transaction
!(Delta (Core.Value era)) -- the Coin consumed by this transaction
!(Delta (Core.Value era)) -- the Coin produced by this transaction
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrBliss - is it okay that I have changed the serialization for this predicate failure? I do not know who all uses the failure serializations.

Copy link
Contributor

@mrBliss mrBliss Oct 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect forall (x :: Word64). toCBOR (word64ToCoin x) == toCBOR (toDelta (word64ToCoin x) to be true, in which case this change is fine.

UPDATE: QuickCheck doesn't find a counterexample on my machine:

prop_DeltaCoin_binary_compat :: Word64 -> Property
prop_DeltaCoin_binary_compat x =
    serialize' (word64ToCoin x) === serialize' (toDelta (word64ToCoin x))

> quickCheckWith prop_DeltaCoin_binary_compat
+++ OK, passed 100 tests.

So I believe this change is safe.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, great! thank you for (quick) checking!

tx = Tx @C txbody wits SNothing
st = runShelleyBase $ applySTSTest @(LEDGER C) (TRC (ledgerEnv, (utxoState, dpState), tx))
-- We test that the serialization of the predicate failure does not return bottom
in serialize' st @?= serialize' st
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a less silly way to enforce that the serialization does not return bottom?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could use rnf, deepseq, or force on serialize' st. What you have works too.

(there are two spaces before the second st)

@@ -40,6 +41,10 @@ type ShelleyBased era =
ChainData (Value era),
SerialisableData (Value era),
SerialisableData (CompactForm (Value era)),
ChainData (Delta (Value era)),
SerialisableData (Delta (Value era)),
Eq (Delta (Value era)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ChainData includes Eq already.

!(Core.Value era) -- the Coin consumed by this transaction
!(Core.Value era) -- the Coin produced by this transaction
!(Delta (Core.Value era)) -- the Coin consumed by this transaction
!(Delta (Core.Value era)) -- the Coin produced by this transaction
Copy link
Contributor

@mrBliss mrBliss Oct 30, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect forall (x :: Word64). toCBOR (word64ToCoin x) == toCBOR (toDelta (word64ToCoin x) to be true, in which case this change is fine.

UPDATE: QuickCheck doesn't find a counterexample on my machine:

prop_DeltaCoin_binary_compat :: Word64 -> Property
prop_DeltaCoin_binary_compat x =
    serialize' (word64ToCoin x) === serialize' (toDelta (word64ToCoin x))

> quickCheckWith prop_DeltaCoin_binary_compat
+++ OK, passed 100 tests.

So I believe this change is safe.

instance Torsor.Torsor Coin where
type Delta Coin = DeltaCoin
addDelta = addDelta
toDelta = toDelta
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a danger of the following happening in modules that import both:

    Ambiguous occurrence ‘toDelta’
    It could refer to
       either ‘Cardano.Ledger.Torsor.toDelta’,
              imported from ‘Cardano.Ledger.Torsor’
           or ‘Shelley.Spec.Ledger.Coin.toDelta’,
              imported from ‘Shelley.Spec.Ledger.Coin’

toDelta :: Coin -> DeltaCoin could be renamed to toDeltaCoin?

The ValueNotConservedUTxO predicate failure contains two values of type
Coin (in the Shelley era, but Core.Value in general). Though the Coin
values in the ledger state are always within the proper bounds
(ie Word64), the failure could produce values outside of this range.
This caused a serialization error for ValueNotConservedUTxO, since we
do not allow the serialization of coins out of the Word64 range.

For the Coin type, we already had a wrapper DeltaCoin which can be
used when we want to intentionally serialize any Coin.
This is now generalized to a Torsor type class, which
ValueNotConservedUTxO now uses.

Resolves: CAD-2168
@JaredCorduan JaredCorduan force-pushed the jc/fix-value-not-conserved-serialization branch from 70339b9 to b57ab4e Compare October 30, 2020 14:18
@mrBliss
Copy link
Contributor

mrBliss commented Oct 30, 2020

bors merge

iohk-bors bot added a commit that referenced this pull request Oct 30, 2020
1955: fix  ValueNotConservedUTxO serialization r=mrBliss a=JaredCorduan

The `ValueNotConservedUTxO` predicate failure contains two values of type `Coin` (in the Shelley era, but `Core.Value` in general). Though the `Coin` values in the ledger state are always within the proper bounds (ie `Word64`), the failure could produce values outside of this range. This caused a serialization error for `ValueNotConservedUTxO`, since we do not allow the serialization of coins out of the `Word64` range.
    
For the `Coin` type, we already had a wrapper `DeltaCoin` which can be used when we want to intentionally serialize any `Coin`. This is now generalized to a `Torsor` type class, which `ValueNotConservedUTxO` now uses (I'm happy to have help with the name...).

Co-authored-by: Jared Corduan <jared.corduan@iohk.io>
@mrBliss mrBliss merged commit f1b1a0c into master Oct 30, 2020
@iohk-bors iohk-bors bot deleted the jc/fix-value-not-conserved-serialization branch October 30, 2020 15:23
@mrBliss
Copy link
Contributor

mrBliss commented Oct 30, 2020

Sorry bors, too slow

@mrBliss
Copy link
Contributor

mrBliss commented Oct 30, 2020

bors cancel

mrBliss added a commit to IntersectMBO/ouroboros-network that referenced this pull request Oct 30, 2020
iohk-bors bot added a commit to IntersectMBO/ouroboros-network that referenced this pull request Oct 30, 2020
2719: Update dependency on cardano-ledger-specs r=mrBliss a=mrBliss

Reason: IntersectMBO/cardano-ledger#1955

Co-authored-by: Thomas Winant <thomas@well-typed.com>
mrBliss added a commit to IntersectMBO/cardano-node that referenced this pull request Oct 30, 2020
This updates the dependencies on `cardano-ledger-specs` and `ouroboros-network`
to bring in IntersectMBO/cardano-ledger#1955

Other visible change: IntersectMBO/ouroboros-network#2714
@iohk-bors
Copy link
Contributor

iohk-bors bot commented Oct 30, 2020

This PR was included in a batch that successfully built, but then failed to merge into master (it was a non-fast-forward update). It will be automatically retried.

@mrBliss
Copy link
Contributor

mrBliss commented Oct 30, 2020

bors cancel

mrBliss added a commit to IntersectMBO/cardano-node that referenced this pull request Oct 30, 2020
This updates the dependencies on `cardano-ledger-specs` and `ouroboros-network`
to bring in IntersectMBO/cardano-ledger#1955

Other visible change: IntersectMBO/ouroboros-network#2714
iohk-bors bot added a commit to IntersectMBO/cardano-node that referenced this pull request Oct 30, 2020
2039: Update: fix ValueNotConservedUTxO serialization r=mrBliss a=mrBliss

This updates the dependencies on `cardano-ledger-specs` and `ouroboros-network`
to bring in IntersectMBO/cardano-ledger#1955

Other visible change: IntersectMBO/ouroboros-network#2714

Co-authored-by: Thomas Winant <thomas@well-typed.com>
JaredCorduan pushed a commit to IntersectMBO/cardano-node that referenced this pull request Nov 3, 2020
This updates the dependencies on `cardano-ledger-specs` and `ouroboros-network`
to bring in IntersectMBO/cardano-ledger#1955

Other visible change: IntersectMBO/ouroboros-network#2714
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants