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

Inconsistent behavior when using a trait parameter #1621

Closed
psq opened this issue May 22, 2020 · 3 comments
Closed

Inconsistent behavior when using a trait parameter #1621

psq opened this issue May 22, 2020 · 3 comments
Assignees
Milestone

Comments

@psq
Copy link
Contributor

psq commented May 22, 2020

Describe the bug
Calling a contract with a Trait parameter works when done dynamically via the api, but not statically when written directly in the contract.

Steps To Reproduce
Clone https://github.com/psq/ClarityTraitExample, run npm install, then run npm test.

The test should pass when the contract gets given the <trait> at runtime.

Now, uncomment line 7 of dispatcher.clar (https://github.com/psq/ClarityTraitExample/blob/master/contracts/dispatcher.clar#L7)

and run the test again: you get this output:

     ExecutionError: Launch contract failed with bad exit code 1: DEBUG [1590123249.800] [src/chainstate/stacks/index/marf.rs:761] Extending off of existing node f02c8037794f6d3f5d1ca34f71f7967779dad231499c7aad6b2080d4ed354154 in /var/folders/10/vfzc9gqn6cs8d2zldp6v83400000gp/T/blockstack-local-1590123249-xaklpx.db/marf
DEBUG [1590123249.800] [src/chainstate/stacks/index/marf.rs:237] Extend f02c8037794f6d3f5d1ca34f71f7967779dad231499c7aad6b2080d4ed354154 to 01af0cc02b0b5383a41934ab1449a1103c501d717a200b68f43e7763987eb111
DEBUG [1590123249.802] [src/vm/database/marf.rs:222] commit_to(01af0cc02b0b5383a41934ab1449a1103c501d717a200b68f43e7763987eb111)
DEBUG [1590123249.802] [src/chainstate/stacks/index/storage.rs:1043] Flush: 01af0cc02b0b5383a41934ab1449a1103c501d717a200b68f43e7763987eb111 to 01af0cc02b0b5383a41934ab1449a1103c501d717a200b68f43e7763987eb111
DEBUG [1590123249.803] [src/chainstate/stacks/index/storage.rs:1075] Flush: identifier of 01af0cc02b0b5383a41934ab1449a1103c501d717a200b68f43e7763987eb111 is 4
Contract initialization error:
TypeError(TraitReferenceType(TraitIdentifier { name: ClarityName("trait-1"), contract_identifier: QualifiedContractIdentifier { issuer: StandardPrincipalData(1, [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]), name: ContractName("define-trait") } }), PrincipalType)
Near:
[SymbolicExpression { expr: List([SymbolicExpression { expr: Atom(ClarityName("wrapped-get-1")), id: 20, span: Span { start_line: 7, start_column: 8, end_line: 7, end_column: 20 } }, SymbolicExpression { expr: LiteralValue(Principal(Contract(QualifiedContractIdentifier { issuer: StandardPrincipalData(22, [170, 194, 122, 127, 229, 5, 234, 50, 91, 65, 67, 183, 136, 232, 138, 100, 80, 127, 53, 160]), name: ContractName("target") }))), id: 21, span: Span { start_line: 7, start_column: 22, end_line: 7, end_column: 69 } }]), id: 19, span: Span { start_line: 7, start_column: 7, end_line: 7, end_column: 71 } }]
      at NativeClarityBinProvider.launchContract (node_modules/@blockstack/clarity/src/providers/clarityBin/index.ts:126:13)
      at processTicksAndRejections (internal/process/task_queues.js:86:5)

which seems to mean that it was expecting a TraitReferenceType but was given a Principal. That's the same value that was passed and worked when calling the contract dynamically.

Expected behavior
Both should be equivalent, and the static version should not report an error of a Principal not being compatible with a Trait.

Environment (please complete the following information):

  • OS: Mac OS 10.14.6
  • Rust version: rustc 1.43.1 (8d69840ab 2020-05-04)
  • Version of the appropriate binary / software package: should be all in package-lock.json of the linked repo

Additional context
Everything to reproduce should be at https://github.com/psq/ClarityTraitExample, but I can provided additional info if needed.

@lgalabru
Copy link
Contributor

It does not look like an error.
In

(use-trait trait-1 .contract-defining-trait.trait-1)
        (define-public (wrapped-get-1 (contract <trait-1>)) 
            (contract-call? contract get-1 u0))
        (print (wrapped-get-1 .target-contract))

The call is (wrapped-get-1 .target-contract) is, indeed receiving a principal.
That being said, I understand that there's a need. Should we be able to infer that in this context, it's a trait reference, or should we add a trait constructor? The latter option might be very limited, and only accept principal literals. Otherwise, we would be opening a door to dynamic dispatch with stored traits references (a function receives a trait, convert it and store it as a principal, and re-construct a a trait-reference later on).
What's your take @kantai ?

@kantai
Copy link
Member

kantai commented Jun 15, 2020

Yeah -- I think we should be able to handle the case, because this would be allowed if it were called via contract-call, e.g.,

;; contract-a
(use-trait trait-1 .contract-defining-trait.trait-1)
(define-public (wrapped-get-1 (contract <trait-1>)) 
     (contract-call? contract get-1 u0))

And then in another contract:

(contract-call? .contract-a wrapped-get-1 .target-contract)

Would work -- the type checker will allow supplying a literal principal instead of a trait reference.

The only reason this doesn't work for calling functions directly is that the FunctionType::check_args function doesn't perform the exact same kind of check as the contract-call? type check does.

@lgalabru
Copy link
Contributor

Addressed with #1679

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

No branches or pull requests

4 participants