def execute(cls, stack: MichelsonStack, stdout: List[str],
             context: AbstractContext):
     a, b = cast(
         Tuple[Union[IntType, NatType, MutezType, TimestampType], ...],
         stack.pop2())
     q_type, r_type = dispatch_types(
         type(a),
         type(b),
         mapping={  # type: ignore
             (NatType, NatType): (NatType, NatType),
             (NatType, IntType): (IntType, NatType),
             (IntType, NatType): (IntType, NatType),
             (IntType, IntType): (IntType, NatType),
             (MutezType, NatType): (MutezType, MutezType),
             (MutezType, MutezType): (NatType, MutezType)
         }
     )  # type: Union[Type[IntType], Type[NatType], Type[TimestampType], Type[MutezType]]
     if int(b) == 0:
         res = OptionType.none(PairType.create_type(args=[q_type, r_type]))
     else:
         q, r = divmod(int(a), int(b))
         if r < 0:
             r += abs(int(b))
             q += 1
         items = [q_type.from_value(q), r_type.from_value(r)]
         res = OptionType.from_some(PairType.from_comb(items))
     stack.push(res)
     stdout.append(format_stdout(cls.prim, [a, b], [res]))  # type: ignore
     return cls(stack_items_added=1)
Exemple #2
0
 def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
     ticket, amounts = cast(Tuple[TicketType, PairType], stack.pop2())
     ticket.assert_type_in(TicketType)
     amounts.assert_type_in(PairType)
     a, b = tuple(amounts)  # type: NatType, NatType
     a.assert_type_equal(NatType)
     b.assert_type_equal(NatType)
     res = ticket.split(int(a), int(b))
     if res is None:
         res = OptionType.none(PairType.create_type(args=[type(ticket), type(ticket)]))
     else:
         res = OptionType.from_some(PairType.from_comb(list(res)))
     stack.push(res)
     stdout.append(format_stdout(cls.prim, [ticket, amounts], [res]))
     return cls()
    def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
        stack_items_added = 0
        src = cast(Union[ListType, MapType], stack.pop1())
        executions = []
        items = []
        popped = [src]
        for elt in src:
            if isinstance(src, MapType):
                elt = PairType.from_comb(list(elt))  # type: ignore
            stack.push(elt)  # type: ignore
            stack_items_added += 1
            stdout.append(format_stdout(cls.prim, popped, [elt]))  # type: ignore
            execution = cls.args[0].execute(stack, stdout, context=context)
            executions.append(execution)
            new_elt = stack.pop1()
            if isinstance(src, MapType):
                items.append((elt[0], new_elt))
            else:
                items.append(new_elt)  # type: ignore
            popped = [new_elt]  # type: ignore

        if items:
            res = type(src).from_items(items)  # type: ignore
        else:
            res = src  # TODO: need to deduce argument types
        stack.push(res)
        stack_items_added += 1
        stdout.append(format_stdout(cls.prim, popped, [res]))  # type: ignore
        return cls(stack_items_added, executions)
Exemple #4
0
    def execute(cls, stack: MichelsonStack, stdout: List[str],
                context: AbstractContext):
        # FIXME: MichelsonProgram copypaste
        parameter_literal, storage_literal = cls.args  # type: ignore

        parameter_type_expr = context.get_parameter_expr()
        storage_type_expr = context.get_storage_expr()
        if parameter_type_expr is None:
            raise Exception('parameter type is not initialized')
        if storage_type_expr is None:
            raise Exception('storage type is not initialized')

        parameter_type = ParameterSection.match(parameter_type_expr)
        storage_type = StorageSection.match(storage_type_expr)
        parameter = parameter_type.from_micheline_value(
            parameter_literal.as_micheline_expr())
        storage = storage_type.from_micheline_value(
            storage_literal.as_micheline_expr())

        parameter.attach_context(context)
        storage.attach_context(context)
        res = PairType.from_comb([parameter.item, storage.item])
        stack.items = []
        stack.push(res)
        stdout.append(format_stdout(f'BEGIN %default', [], [res]))
        return cls(stack_items_added=1)
Exemple #5
0
 def begin(self, stack: MichelsonStack, stdout: List[str],
           context: ExecutionContext):
     self.parameter_value.attach_context(context)
     self.storage_value.attach_context(context)
     res = PairType.from_comb(
         [self.parameter_value.item, self.storage_value.item])
     stack.push(res)
     stdout.append(format_stdout(f'BEGIN %{self.entrypoint}', [], [res]))
Exemple #6
0
 def execute(cls, stack: MichelsonStack, stdout: List[str],
             context: AbstractContext):
     left, right = stack.pop2()
     res = PairType.from_comb([left, right])
     stack.push(res)
     stdout.append(format_stdout(cls.prim, [left, right],
                                 [res]))  # type: ignore
     return cls(stack_items_added=1)
Exemple #7
0
 def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
     count = cls.args[0].get_int()
     assert count >= 2, f'invalid argument, must be >= 2'
     leaves = stack.pop(count=count)
     res = PairType.from_comb(leaves)
     stack.push(res)
     stdout.append(format_stdout(cls.prim, leaves, [res], count))
     return cls()
Exemple #8
0
 def end(self, stack: MichelsonStack, stdout: List[str], output_mode='readable') \
         -> Tuple[List[dict], Any, List[dict], PairType]:
     res = cast(PairType, stack.pop1())
     assert len(stack) == 0, f'stack is not empty: {repr(stack)}'
     res.assert_type_equal(PairType.create_type(args=[
         ListType.create_type(args=[OperationType]),
         self.storage.args[0]
     ]), message='list of operations + resulting storage')
     operations = [op.content for op in res.items[0]]
     lazy_diff = []
     storage = res.items[1].aggregate_lazy_diff(lazy_diff).to_micheline_value(mode=output_mode)
     stdout.append(format_stdout(f'END %{self.entrypoint}', [res], []))
     return operations, storage, lazy_diff, res
Exemple #9
0
 def execute(cls, stack: MichelsonStack, stdout: List[str],
             context: AbstractContext):
     src = cast(Union[ListType, MapType, SetType], stack.pop1())
     executions = []
     popped = [src]
     for elt in src:
         if isinstance(src, MapType):
             elt = PairType.from_comb(list(elt))
         stack.push(elt)
         stdout.append(format_stdout(cls.prim, popped, [elt]))
         execution = cls.args[0].execute(stack, stdout, context=context)
         executions.append(execution)
         popped = []
     return cls(executions)
Exemple #10
0
    def execute(cls, stack: MichelsonStack, stdout: List[str], context: AbstractContext):
        # FIXME: MichelsonProgram copypaste
        debug, context.debug = context.debug, False  # type: ignore

        res = cast(PairType, stack.pop1())
        if len(stack):
            raise Exception(f'Stack is not empty: {stack}')
        res.assert_type_equal(
            PairType.create_type(
                args=[
                    ListType.create_type(args=[OperationType]),
                    StorageSection.match(context.get_storage_expr()).args[0]
                ],
            ),
            message='list of operations + resulting storage',
        )
        operations = ListType(items=[op for op in res.items[0]])  # type: ignore
        lazy_diff = []  # type: ignore
        storage = res.items[1].aggregate_lazy_diff(lazy_diff)
        stdout.append(format_stdout(f'END %default', [res], []))

        result = PairType.from_comb([operations, storage])
        context.debug = debug  # type: ignore
        return cls(lazy_diff=lazy_diff, result=result)
Exemple #11
0
 def execute(cls, stack: 'MichelsonStack', stdout: List[str],
             context: AbstractContext):
     points = cast(ListType, stack.pop1())
     points.assert_type_equal(
         ListType.create_type(args=[
             PairType.create_type(args=[BLS12_381_G1Type, BLS12_381_G2Type])
         ]))
     prod = FQ12.one()
     for pair in points:
         g1, g2 = tuple(
             iter(pair))  # type: BLS12_381_G1Type, BLS12_381_G2Type
         prod = prod * bls12_381.pairing(g2.to_point(), g1.to_point())
     res = BoolType.from_value(FQ12.one() == prod)
     stack.push(res)
     stdout.append(format_stdout(cls.prim, [points], [res]))
     return cls()
Exemple #12
0
    def test_execute(self) -> None:
        # Arrange
        interpreter = Interpreter()
        code = "PUSH int 1; PUSH int 2; PAIR"

        # Act
        result = interpreter.execute(code)

        # Assert
        self.assertEqual(None, result.error)
        self.assertEqual(
            [
                "PUSH / _ => 1",
                "PUSH / _ => 2",
                "PAIR / 2 : 1 => (2 * 1)",
            ],
            result.stdout,
        )
        self.assertEqual([PairType((IntType(2), IntType(1)))], interpreter.stack.items)
Exemple #13
0
    def test_execute_rollback(self) -> None:
        # Arrange
        interpreter = Interpreter()
        code = "PUSH int 1; PUSH int 2; PAIR"
        bad_code = "PUSH int 1; PAIR; PAIR;"

        # Act
        interpreter.execute(code)
        result = interpreter.execute(bad_code)

        # Assert
        self.assertIsInstance(result.error, MichelsonRuntimeError)
        self.assertEqual(
            [
                "PUSH / _ => 1",
                "PAIR / 1 : (2 * 1) => (1 * (2 * 1))",
                "PAIR: got 1 items on the stack, want to pop 2",
            ],
            result.stdout,
        )
        self.assertEqual([PairType((IntType(2), IntType(1)))], interpreter.stack.items)
Exemple #14
0
 def end(self,
         stack: MichelsonStack,
         stdout: List[str],
         output_mode='readable'
         ) -> Tuple[List[dict], Any, List[dict], PairType]:
     """Finish contract execution"""
     res = cast(PairType, stack.pop1())
     if len(stack):
         raise Exception(f'Stack is not empty: {repr(stack)}')
     res.assert_type_equal(
         PairType.create_type(args=[
             ListType.create_type(args=[OperationType]),
             self.storage.args[0]
         ], ),
         message='list of operations + resulting storage',
     )
     operations = [op.content for op in res.items[0]]  # type: ignore
     lazy_diff = []  # type: ignore
     storage = res.items[1].aggregate_lazy_diff(
         lazy_diff).to_micheline_value(mode=output_mode)
     stdout.append(format_stdout(f'END %{self.entrypoint}', [res], []))
     return operations, storage, lazy_diff, res
Exemple #15
0
    def test_execute_contract_operations(self) -> None:
        # Arrange
        interpreter = Interpreter()
        code = """
            PATCH SENDER "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb" ;
            PATCH BALANCE 200 ;
            
            parameter mutez ;
            storage unit ;
            
            BEGIN 100 Unit ;
            
                CAR ;
                DUP ;
                BALANCE ;
                IFCMPLT
                    { FAIL }
                    {
                        SENDER ;
                        CONTRACT unit ;
                        IF_NONE
                            { FAIL }
                            {
                                SWAP ;
                                UNIT ;
                                TRANSFER_TOKENS ;
                                NIL operation ;
                                SWAP ;
                                CONS ;
                                UNIT ;
                                SWAP ;
                                PAIR
                            } ;
                    };
            COMMIT
        """

        # Act
        result = interpreter.execute(code)

        # Assert
        self.assertEqual(None, result.error)
        self.assertEqual(
            [
                "parameter: updated",
                "storage: updated",
                "BEGIN %default / _ => (0.0001 * Unit)",
                "CAR / (0.0001 * Unit) => 0.0001",
                "DUP / 0.0001 => 0.0001 : 0.0001",
                "BALANCE / _ => 0.0002",
                "COMPARE / 0.0002 : 0.0001 => 1",
                "LT / 1 => False",
                "IF / False => _",
                "SENDER / _ => tz1VSU…cjb",
                "CONTRACT: skip type checking for tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb",
                "CONTRACT / tz1VSU…cjb => tz1VSU…cjb%default?",
                "IF_NONE / tz1VSU…cjb%default? => tz1VSU…cjb%default",
                "SWAP / tz1VSU…cjb%default : 0.0001 => 0.0001 : tz1VSU…cjb%default",
                "UNIT / _ => Unit",
                "TRANSFER_TOKENS / Unit : 0.0001 : tz1VSU…cjb%default => transaction",
                "NIL / _ => []",
                "SWAP / [] : transaction => transaction : []",
                "CONS / transaction : [] => [transaction]",
                "UNIT / _ => Unit",
                "SWAP / Unit : [transaction] => [transaction] : Unit",
                "PAIR / [transaction] : Unit => ([transaction] * Unit)",
                "END %default / ([transaction] * Unit) => _",
            ],
            result.stdout,
        )
        commit_instruction = next((i for i in result.instructions.items[::-1]
                                   if isinstance(i, CommitInstruction)))
        self.assertEqual(
            PairType((
                ListType([
                    OperationType({
                        "kind": "transaction",
                        "source": "KT1BEqzn5Wx8uJrZNvuS9DVHmLvG9td3fDLi",
                        "destination": "tz1VSUr8wwNhLAzempoch5d6hLRiTh8Cjcjb",
                        "amount": "100",
                        "parameters": {
                            "entrypoint": "default",
                            "value": {
                                "prim": "Unit"
                            },
                        },
                    })
                ]),
                UnitType(),
            )),
            commit_instruction.result,
        )