digital-asset / daml

The Daml smart contract language
https://www.digitalasset.com/developers
Other
803 stars 203 forks source link

Lookup archived contracts may succeed when combined with rollback exceptions #14107

Closed remyhaemmerle-da closed 2 years ago

remyhaemmerle-da commented 2 years ago

Affected Daml version

1.18 to 2.2

Bug description

LookupByKey of a archived contract may succeed if in the same transaction

  1. the contract with a key K is archived (by id)
  2. a first lookup over K is done (this lookup fails as excepted), but it is roll-backed.
  3. a second lookup over K now succeeds.

To reproduce

Here is a script that illustrates the problem.

module Test where

import DA.Assert ((===))
import DA.Optional (isSome)
import DA.Exception (throw, GeneralError(..))
import Daml.Script

template K
  with
    sig: Party
  where
    signatory sig
    key sig: Party
    maintainer key

template Helper
  with sig: Party
  where
    signatory sig
    choice Go1: Bool
      with cid: ContractId K
      controller sig
      do
        exercise cid Archive
        try do
          None <- lookupByKey @K sig
          throw (GeneralError "")
        catch (GeneralError _) -> pure ()
        result <- lookupByKey @K sig
        pure $ isSome result

    choice Go2 : ()
      with cid : ContractId K
      controller sig
      do -- consume key, don’t change
         -- keys & globalKeyInputs
         archive cid
         -- populate globalKeyInputs
         try do
           None <- lookupByKey @K sig
           error "abc"
         catch
           GeneralError _ -> pure ()
         -- incorrect duplicate key error
         create (K sig)
         pure ()

test1 : Script ()
test1 = script do
  alice <- allocateParty "alice"
  cid <- submit alice $ createCmd (K alice)
  helper <- submit alice $ createCmd (Helper alice)
  r <- submit alice $ exerciseCmd helper (Go1 cid)
  r === False

test2 : Script ()
test2 = script do
  alice <- allocateParty "p"
  cid <- submit alice $ createCmd (K alice) 
  submit alice $ createAndExerciseCmd (Helper alice) (Go2 cid) 

Expected behavior

Additional context

dylant-da commented 2 years ago
IDE 1.18.0
    test1: failed because r === True
    test2: failed because unique key violation
IDE 2.2.0
    test1 failed because r === True
    test2 failed because unique key violation
1.18.0 kv-sandbox
    test1 failed because INTERNALLY_INCONSISTENT_KEYS
    test2 submit failed due to ALREADY_EXISTS: DUPLICATE_CONTRACT_KEY
1.18.0 daml-on-sql
    test1 Command submit failed: FAILED_PRECONDITION: INCONSISTENT_CONTRACT_KEY
    test2 Command submit failed: ALREADY_EXISTS: DUPLICATE_CONTRACT_KEY
2.2.0 canton-sandbox
    test1 failed because INVALID_ARGUMENT: MALFORMED_REQUEST
    test2 submit failed due to ALREADY_EXISTS: DUPLICATE_CONTRACT_KEY