cadence icon indicating copy to clipboard operation
cadence copied to clipboard

Adding default implementations to interface methods

Open bjartek opened this issue 3 years ago • 5 comments

Issue To Be Solved

In order to evolve contracts and standards like the NFT contract Interface having some way to specify the default behavior of a interface method is needed.

Say you want to add a getName(): String method to all INFT types. In order to do that safely the sanes way is IMHO to add support for default implementations.

Suggested Solution

Interface methods can today contain pre and post blocks. One suggestion from bluesign is that they can also contain a default block. And when implementing an interface methods that have a default block can be left unimplemented in the implementing code

Context

See here for context https://github.com/onflow/flow-nft/issues/9

bjartek avatar Jun 08 '21 19:06 bjartek

Notes

  • Current state: We already have support for declaring pre/post-conditions in interface function bodies and linking them into execution

  • We want to keep support for function declarations in interfaces that have no body, or just pre and post conditions

    struct interface X {
       fun foo() { only pre, post ... }
       fun bar()
    }
    
  • We want to add support for function declarations in interfaces with a body

    struct interface X {
        fun foo() {}
    }
    
  • Parsing (in runtime/parser2):

    • Already done: Interface declarations are parsed like composite declarations
    • Add test
  • Checking (in runtime/sema):

    • Allow function bodies in interface
      • see Checker.checkInterfaceSpecialFunctionBlock
      • Change tests to be valid, e.g. TestCheckInvalidInterfaceWithFunctionImplementation
      • Change test names
    • Check the interface function bodies:
      • Checker.checkInterfaceFunctions calls visitFunctionDeclaration:
        • mustExit flag needs rename/change, e.g. OK if there are only pre and post conditions
        • declare should be true (?), as other functions should be able to refer to the function
        • checkResources should be true
    • Composite conforming to interface
      • Note: Implicit conformance when interface requires concrete implementation
      • see Checker.checkCompositeConformance
      • Missing function? check if interface member is function, and if so if it has a block, not a missing member
      • report of MissingFunctionBodyError should stay
      • Record which interface type has default implementation for composite function. Needed to link in default implementation at run-time in interpreter
    • Edge case: Report an error when multiple interfaces provide a default implementation
    • Checker/sema tests are in runtime/tests/checker
  • Execution:

    • Composite functions are already wrapped with pre/post conditions of the interface
    • A wrapper is type FunctionWrapper = func(inner FunctionValue) FunctionValue.
      • Pseudocode:
        return func(body func) {
            preConditions()
            body()
            postConditions()
        }
        
    • See Interpreter.functionConditionsWrapper
    • How is interface code linked into composite? => record which interface for which function provides the default implementation in checker! -> semantic
      • CompositeValue.InitializeFunctions links in functions for composite
      • Declared in ... EOF

turbolent avatar Jun 09 '21 20:06 turbolent

merge after secure cadence release

j1010001 avatar May 20 '22 18:05 j1010001

Would it be possible to reconsider and have this as part of that release? If we can do that and at the same time implement getViews and resolveViews in NFT contract it would solve the linking problem that is a very hard one.

bjartek avatar May 23 '22 07:05 bjartek

The code for the release was feature frozen a few months ago and then received security audits, so unfortunately we will not be able to get it into this release, but will definitely try to get it into the next release, given that is is now complete.

turbolent avatar Jun 03 '22 18:06 turbolent

good to go once we verify there are no security implications, might need adding more test cases.

j1010001 avatar Jul 18 '22 18:07 j1010001