digital-asset / daml

The Daml smart contract language
https://www.digitalasset.com/developers
794 stars 199 forks source link

[BUG] JS codegen mutates interface object resulting in incorrect template ids #13504

Closed cocreature closed 2 years ago

cocreature commented 2 years ago

Affected Daml version

2.1.0-snapshot.20220325.9626.0.4a483381

Bug description

The JS codegen generates code of the form

exports.T = Object.assign(Interface, {…})

However, Object.assign mutates the target. That means that if I have two templates that both implement the same interface they will both share the object and thereby things like the template id which is clearly very wrong. We cannot mutate the interface here.

To reproduce

  1. Download create-daml-app.tar.gz
  2. Run daml start
  3. cd ui && npm install
  4. npm start
  5. Look at the console logs which print out the template objects of T and T2 and very that they both point to T
    T: {"templateId":"ac5735e7add80f68378af98aba833a7ebdaf70cdfe265444ed1d0ff93f55ec4e:IfaceTemplate:T","InterfaceChoice":{"choiceName":"InterfaceChoice","argumentDecoder":{},"resultDecoder":{}},"keyDecoder":{},"decoder":{},"Archive":{"choiceName":"Archive","argumentDecoder":{},"resultDecoder":{}}}
    T2: {"templateId":"ac5735e7add80f68378af98aba833a7ebdaf70cdfe265444ed1d0ff93f55ec4e:IfaceTemplate:T","InterfaceChoice":{"choiceName":"InterfaceChoice","argumentDecoder":{},"resultDecoder":{}},"keyDecoder":{},"decoder":{},"Archive":{"choiceName":"Archive","argumentDecoder":{},"resultDecoder":{}}} 

Expected behavior

I can work with two templates implementing the same interface correctly.

S11001001 commented 2 years ago

We assumed assign added to the last argument, but it adds to the first argument:

https://github.com/digital-asset/daml/blob/e28ef7d3eb45eb1560411cbc244ce313cecda355/language-support/ts/codegen/src/TsCodeGenMain.hs#L392-L397