Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions daml/dars.lock
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,8 @@ splice-amulet-name-service 0.1.6 a208aab2c4a248ab2eff352bd382f8b3bbadc92464123db
splice-amulet-name-service 0.1.7 ba7806d9b2d593eac74a050161c54ae1325d170bf175cb66a9c1e5e5ffb88c3d
splice-amulet-name-service 0.1.8 efeb3f9b2b92e55fac4ec2d6164f95407a01477240c7465e576df4e310f54bd3
splice-amulet-name-service 0.1.9 f1b5915ad45ded616f43f83c735b7ee158b5eb58abe758a721e50eee19b3e531
splice-amulet-name-service-test 0.1.23 b6fa2d3007ff0298e2889f2cab9ee1d0f02f187db3ed139f37b65cadc36bc57e
splice-amulet-test 0.1.22 de4be9668174d8855fe2404abb65bccbb835c18114ec232839da9e6f370d3820
splice-amulet-name-service-test 0.1.23 041170aad8282d13620a0d573d91b649ab599f95833d091342c7e20f2abc8c5b
splice-amulet-test 0.1.22 625cdb9546448b07d634680fc2ad093a136450fab7de439e120d10f2cacedd4d
splice-api-featured-app-v1 1.0.0 7804375fe5e4c6d5afe067bd314c42fe0b7d005a1300019c73154dd939da4dda
splice-api-featured-app-v2 1.0.0 dd22e3e168a8c7fd0313171922dabf1f7a3b131bd9bfc9ff98e606f8c57707ea
splice-api-token-allocation-instruction-v1 1.0.0 275064aacfe99cea72ee0c80563936129563776f67415ef9f13e4297eecbc520
Expand Down Expand Up @@ -78,7 +78,7 @@ splice-dso-governance 0.1.6 4e7653cfbf7ca249de4507aca9cd3b91060e5489042a522c589d
splice-dso-governance 0.1.7 d406eba1132d464605f4dae3edf8cf5ecbbb34bd8edef0e047e7e526d328718c
splice-dso-governance 0.1.8 1790a114f83d5f290261fae1e7e46fba75a861a3dd603c6b4ef6b67b49053948
splice-dso-governance 0.1.9 9ee83bfd872f91e659b8a8439c5b4eaf240bcf6f19698f884d7d7993ab48c401
splice-dso-governance-test 0.1.30 9c41327184c94a7ae63be2e5ec372da53d95b5bf8ec88d8148af2da854be32bd
splice-dso-governance-test 0.1.30 d406b76b72ab6631a275d2916b4c6c6c5caaa7cce4a5ca9fb1b9fff690ac6a2a
splice-token-standard-test 1.0.13 7d1fa6161633dc6998ad6e56653990e6d17fe0bab2a5f12a0500974a08fa0a41
splice-token-test-dummy-holding 0.0.1 1cd171c6c42ab46dc9cf12d80c6111369e00cea5cdf054924b4f26ce94b1ef5b
splice-token-test-dummy-holding 0.0.2 4f40fb033ef3db89623642c1b494e846097fa32af138b3864a63aa15937a323d
Expand Down Expand Up @@ -149,7 +149,7 @@ splice-wallet-payments 0.1.6 6124379528eeb6fa17ecdab15577c29abb33d0c0d34dc5f2680
splice-wallet-payments 0.1.7 4e3e0d9cdadf80f4bf8f3cd3660d5287c084c9a29f23c901aabce597d72fd467
splice-wallet-payments 0.1.8 e48ea337ee3335c8bb3206a2501ce947ac1a7bdb1825cee8f28bad64f5a7bc4b
splice-wallet-payments 0.1.9 7f4e081ad96f2ccded0c053b0cf5ddddae1139dfc3bb89cefcf77ea70f2cecb7
splice-wallet-test 0.1.23 34c3a31a9e8c60662739a9f699ccdbd8d5c93e64c155855b7edfe5ddd6701bdc
splice-wallet-test 0.1.23 1b9364a94e9fd7f8bcb96893417287078d4b181c4736ee4268361d9fed1e383a
splitwell 0.1.0 075c76de553ab88383a7c69de134afa82aacfdf8ea8fcfe8852c4b199c3b2669
splitwell 0.1.1 ccb1a0215053062202052e1a052f9214da3fdae5253a6d43e2e155ff4f57fe75
splitwell 0.1.10 d42676a366f7ca7a2409974dd3054aa4d83ab29baa3b2086ad021407b0a1a295
Expand All @@ -171,4 +171,4 @@ splitwell 0.1.6 872da0dd7986fd768930f85d6a7310a94a0ef924e7fbb7bb7a4e149f2b5feb74
splitwell 0.1.7 841d1c9c86b5c8f3a39059459ecd8febedf7703e18f117300bb0ebf4423db096
splitwell 0.1.8 63b8153a08ceb4bf40d807acc5712372c3eac548c266be4d5e92470b4f655515
splitwell 0.1.9 b6267905698d2798b9ef171e27d49fb88e052ec0ec0e0675a3a1b275c7d037d4
splitwell-test 0.1.23 781e502852284a6ee23252ec7fbbee4832145bc661f28415281ea36c8860fe95
splitwell-test 0.1.23 9c8426b205f8546f55306dd98644df5110cdd9c0e906cbcd7aa4cb82ac78c05f
52 changes: 13 additions & 39 deletions daml/splice-amulet-test/daml/Splice/Testing/CryptoHashProxy.daml
Original file line number Diff line number Diff line change
Expand Up @@ -3,48 +3,22 @@

module Splice.Testing.CryptoHashProxy where

import DA.Text (intercalate, sha256)

-- TODO(#4749): When Splice.Amulet.CryptoHash is merged, remove these
-- test-only copies and import from the real module instead.

-- | Hash a text scalar: sha256(value).
-- Matches: instance Hashable Text where hash = hashText . id
hashText : Text -> Text
hashText = sha256

-- | Hash a list of already-hashed elements.
-- Matches: hashListInternal ts = sha256(intercalate "|" (show(length ts) :: ts))
hashList : [Text] -> Text
hashList elems =
let parts = show (length elems) :: elems
in sha256 (intercalate "|" parts)

-- | Hash a variant with a tag and field hashes.
-- Matches: hashVariant tag fields = sha256(intercalate "|" (tag :: show(length fields) :: fields))
hashVariant : Text -> [Text] -> Text
hashVariant tag fieldHashes =
let parts = tag :: show (length fieldHashes) :: fieldHashes
in sha256 (intercalate "|" parts)

-- | Hash a record as a list of field hashes.
hashRecord : [Text] -> Text
hashRecord = hashList
import Splice.Amulet.CryptoHash (Hash(..), Hashable(..), hashRecord, hashVariant)

-- | Hash a MintingAllowance{provider, amount}.
hashMintingAllowance : Text -> Text -> Text
hashMintingAllowance : Text -> Text -> Hash
hashMintingAllowance provider amount =
hashRecord [hashText provider, hashText amount]
hashRecord [hash provider, hash amount]

-- | Hash a BatchOfMintingAllowances variant.
hashBatchOfMintingAllowances : [Text] -> Text
hashBatchOfMintingAllowances : [Hash] -> Hash
hashBatchOfMintingAllowances allowanceHashes =
hashVariant "BatchOfMintingAllowances" [hashList allowanceHashes]
hashVariant "BatchOfMintingAllowances" [hash allowanceHashes]

-- | Hash a BatchOfBatches variant.
hashBatchOfBatches : [Text] -> Text
hashBatchOfBatches : [Hash] -> Hash
hashBatchOfBatches childHashes =
hashVariant "BatchOfBatches" [hashList childHashes]
hashVariant "BatchOfBatches" [hash childHashes]

-- | Proxy template exposing hash functions as exercisable choices.
-- Allows Scala integration tests to call Daml hash functions via the
Expand All @@ -58,36 +32,36 @@ template CryptoHashProxy with
with
input : Text
controller owner
do pure (hashText input)
do pure (hash input).value

nonconsuming choice CryptoHashProxy_HashList : Text
with
elems : [Text]
controller owner
do pure (hashList elems)
do pure (hash (map Hash elems)).value

nonconsuming choice CryptoHashProxy_HashVariant : Text
with
tag : Text
fields : [Text]
controller owner
do pure (hashVariant tag fields)
do pure (hashVariant tag (map Hash fields)).value

nonconsuming choice CryptoHashProxy_HashMintingAllowance : Text
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Shouldn't these be modified to work with actual data?

data MintingAllowance = MintingAllowance with
    provider : Party
    amount : Decimal

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

I looked into this but it doesn't work cleanly for the equivalence test.

The issue is that the Daml Hashable instances for Party and
Decimal apply their own serialization (partyToText, show) before
hashing, and these don't necessarily match the text strings we pass to
the SQL side. For example, show on Decimal(0) produces
"0.0000000000" not "0", and party IDs go through partyToText.

The purpose of this test is to verify the hash algorithm is equivalent
(Daml == SQL), not to test Daml's type serialization. Keeping the proxy
choices as Text args lets us control the exact string representation
on both sides, which is what we need for the equivalence comparison.

The proxy still uses the real Splice.Amulet.CryptoHash primitives
(hash, hashRecord, hashVariant) — it's only the domain composites
(hashMintingAllowance, batch hashes) that stay as text-based wrappers
to avoid the serialization mismatch.

Copy link
Copy Markdown
Contributor

@dfordivam dfordivam Apr 21, 2026

Choose a reason for hiding this comment

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

Ultimately we have to make sure that hash on Batch matches what we compute in sql.
Can we show that this is the case?
If there are any serialization mismatches here, then we have an issue on the SQL/scala side.

    choice ProcessRewardsV2_ProcessBatch : ProcessRewardsV2_ProcessBatchResult
      with
        batch : Batch
        providersWithWrongVettingState : Set Party
          -- ^ Service providers that do not have the correct vetting state for receiving rewards.
      observer batchProviders providersWithWrongVettingState batch
      controller dso
      do
        let actualHash = CryptoHash.hash batch
        require "batch hash matches" (actualHash == batchHash)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you could say that it is not feasible to match the daml serialization in scala/sql. In that case we must change the instance of Batch in daml. But that will require further discussion with Simon

with
provider : Text
amount : Text
controller owner
do pure (hashMintingAllowance provider amount)
do pure (hashMintingAllowance provider amount).value

nonconsuming choice CryptoHashProxy_HashBatchOfMintingAllowances : Text
with
allowanceHashes : [Text]
controller owner
do pure (hashBatchOfMintingAllowances allowanceHashes)
do pure (hashBatchOfMintingAllowances (map Hash allowanceHashes)).value

nonconsuming choice CryptoHashProxy_HashBatchOfBatches : Text
with
childHashes : [Text]
controller owner
do pure (hashBatchOfBatches childHashes)
do pure (hashBatchOfBatches (map Hash childHashes)).value
Loading