Skip to content

Commit

Permalink
adapting for the kernel
Browse files Browse the repository at this point in the history
  • Loading branch information
m-kus committed Feb 27, 2020
1 parent f3afdea commit 5c92c24
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 39 deletions.
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
local:
pip install . --force --no-deps
debug:
pip install . --force --no-deps
8 changes: 8 additions & 0 deletions pytezos/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,14 @@ def parse_public_key(data: bytes):
return base58_encode(data[1:], key_prefix[data[:1]]).decode()


def parse_chain_id(data: bytes):
return base58_encode(data, b'Net').decode()


def parse_signature(data: bytes):
return base58_encode(data, b'sig').decode()


def forge_address(value, tz_only=False) -> bytes:
prefix = value[:3]
address = base58.b58decode_check(value)[3:]
Expand Down
25 changes: 13 additions & 12 deletions pytezos/repl/blockchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def do_self(ctx: Context, prim, args, annots):
assert p_type_expr, f'parameter type is not initialized'

entrypoint = next((a for a in annots if a[0] == '%'), '%default')
ctx.print(f' use {entrypoint};')
ctx.printf(f' use {entrypoint};')

p_type_expr = get_entry_expr(p_type_expr, entrypoint)
res = Contract.new(SELF_ADDRESS + entrypoint, type_expr=p_type_expr)
Expand All @@ -83,20 +83,21 @@ def do_source(ctx: Context, prim, args, annots):

@instruction('NOW')
def do_now(ctx: Context, prim, args, annots):
chain_id = ctx.get('CHAIN_ID')
if chain_id:
now = pytezos.using(get_network_by_chain_id(chain_id)).now()
else:
now = int(datetime.utcnow().timestamp())

res = Timestamp(now)
res = ctx.get('NOW')
if not res:
chain_id = ctx.get('CHAIN_ID')
if chain_id:
now = pytezos.using(get_network_by_chain_id(chain_id)).now()
else:
now = int(datetime.utcnow().timestamp())
res = Timestamp(now)
ctx.push(res, annots=annots)


def check_contract(ctx: Context, address, type_expr):
chain_id = ctx.get('CHAIN_ID')
if not chain_id:
ctx.print(' skip check;')
ctx.printf(' skip check;')
return True

network = get_network_by_chain_id(chain_id)
Expand All @@ -106,9 +107,9 @@ def check_contract(ctx: Context, address, type_expr):
if expr_equal(type_expr, ci.contract.parameter.code):
return True
else:
ctx.print(' type mismatch;')
ctx.printf(' type mismatch;')
except Exception:
ctx.print(' not found;')
ctx.printf(' not found;')

return False

Expand All @@ -117,7 +118,7 @@ def check_contract(ctx: Context, address, type_expr):
def do_address(ctx: Context, prim, args, annots):
top = ctx.pop1()
assert_stack_type(top, Contract)
res = Address.new(str(top))
res = Address.new(str(top)[:36])
ctx.push(res, annots=annots)


Expand Down
26 changes: 19 additions & 7 deletions pytezos/repl/context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import re
from copy import deepcopy
from pprint import pformat
from typing import List

Expand All @@ -8,13 +9,13 @@

class Context:

def __init__(self, stack=None, debug=True):
def __init__(self, stack=None, meta=None, debug=True):
self.stack = stack or []
self.meta = meta or {}
self.protected = 0
self.meta = dict()
self.stdout = list()
self.exec_depth = 0
self.debug = debug
self.stdout = list()

def protect(self, count: int):
assert len(self.stack) >= count, f'got {len(self.stack)} items, wanted to protect {count}'
Expand All @@ -40,7 +41,7 @@ def pop(self, count: int) -> List[StackItem]:
f'got {len(self.stack) - self.protected} items, requested {count} '
res = [self.stack.pop(self.protected) for _ in range(count)]
if count <= 3:
body = ', '.join(map(repr, res))
body = ', '.join(map(repr, res)) # TODO: restrict line length
else:
body = f'{count} items'
self._print(f' pop {body};')
Expand Down Expand Up @@ -76,14 +77,17 @@ def drop_all(self):
self._print(f' drop all;')

def dump(self, count: int):
count = min(count, len(self.stack))
return self.stack[:count]
if len(self.stack) > 0:
count = min(count, len(self.stack))
return self.stack[:count]
else:
return 'stack is empty'

def _print(self, message):
if self.debug:
self.stdout.append(message)

def print(self, template: str):
def printf(self, template: str):
def format_stack_item(match):
i = int(match.groups()[0])
assert i < len(self.stack), f'requested {i}th element, got only {len(self.stack)} items'
Expand All @@ -106,3 +110,11 @@ def __len__(self) -> int:

def __repr__(self):
return pformat(self.stack)

def __deepcopy__(self, memodict={}):
ctx = Context(stack=deepcopy(self.stack),
meta=deepcopy(self.meta),
debug=self.debug)
ctx.protected = self.protected
ctx.exec_depth = self.exec_depth
return ctx
24 changes: 17 additions & 7 deletions pytezos/repl/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,31 @@
from pytezos.encoding import is_kt
from pytezos.repl.control import instruction, do_interpret
from pytezos.repl.context import Context, StackItem
from pytezos.repl.parser import get_int, get_string, parse_prim_expr, get_entry_expr
from pytezos.repl.parser import get_int, get_string, get_bool, parse_prim_expr, get_entry_expr
from pytezos.repl.types import Pair, Mutez, Address, ChainID, Timestamp

helpers_prim = ['DUMP', 'PRINT', 'DROP_ALL', 'EXPAND', 'RUN', 'PATCH', 'UNSET', 'INCLUDE']
patch_prim = ['ADDRESS', 'AMOUNT', 'BALANCE', 'CHAIN_ID', 'SENDER', 'SOURCE', 'NOW']
helpers_prim = ['DUMP', 'PRINT', 'DROP_ALL', 'EXPAND', 'RUN', 'PATCH', 'INCLUDE', 'DEBUG']
patch_prim = ['AMOUNT', 'BALANCE', 'CHAIN_ID', 'SENDER', 'SOURCE', 'NOW']


@instruction('DUMP', args_len=1)
def do_dump(ctx: Context, prim, args, annots):
return ctx.dump(count=get_int(args[0]))


@instruction('DUMP')
def do_dump(ctx: Context, prim, args, annots):
return ctx.dump(count=len(ctx))


@instruction('PRINT', args_len=1)
def do_print(ctx: Context, prim, args, annots):
ctx.print(template=get_string(args[0]))
ctx.printf(template=f' {get_string(args[0])};')


@instruction('DEBUG', args_len=1)
def do_debug(ctx: Context, prim, args, annots):
ctx.debug = get_bool(args[0])


@instruction('DROP_ALL')
Expand All @@ -37,7 +47,7 @@ def do_run(ctx: Context, prim, args, annots):
assert p_type_expr, f'parameter type is not initialized'

entrypoint = next((a for a in annots if a[0] == '%'), '%default')
ctx.print(f' use {entrypoint};')
ctx.printf(f' use {entrypoint};')

p_type_expr = get_entry_expr(p_type_expr, entrypoint)
parameter = StackItem.parse(args[0], p_type_expr)
Expand All @@ -59,7 +69,7 @@ def do_run(ctx: Context, prim, args, annots):

@instruction('PATCH', args_len=2)
def do_patch(ctx: Context, prim, args, annots):
key, = parse_prim_expr(args[0])
key, _ = parse_prim_expr(args[0])
assert key in patch_prim, f'expected one of {", ".join(patch_prim)}, got {args[0]}'
if key in ['AMOUNT', 'BALANCE']:
res = Mutez(get_int(args[1]))
Expand All @@ -76,7 +86,7 @@ def do_patch(ctx: Context, prim, args, annots):

@instruction('PATCH', args_len=1)
def do_unset(ctx: Context, prim, args, annots):
key, = parse_prim_expr(args[0])
key, _ = parse_prim_expr(args[0])
assert key in patch_prim, f'expected one of {", ".join(patch_prim)}, got {args[0]}'
ctx.unset(key)

Expand Down
21 changes: 12 additions & 9 deletions pytezos/repl/interpreter.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from copy import deepcopy
from pprint import pformat, pprint
from pprint import pformat

from pytezos.michelson.grammar import MichelsonParser, MichelsonParserError
from pytezos.michelson.converter import michelson_to_micheline, micheline_to_michelson
Expand All @@ -21,7 +21,8 @@ def format_stack_item(item: StackItem):


def format_stdout(items):
return ''.join(items)
res = ''.join(items).lstrip('\n')
return res if any(map(lambda x: x in res, ['\n', 'PRINT'])) else ''


def format_result(result):
Expand All @@ -30,7 +31,7 @@ def format_result(result):
elif isinstance(result, StackItem):
return [format_stack_item(result)]
elif isinstance(result, list):
if isinstance(result[0], StackItem):
if len(result) > 0 and isinstance(result[0], StackItem):
return list(map(format_stack_item, result))
else:
return micheline_to_michelson(result)
Expand Down Expand Up @@ -71,27 +72,29 @@ def execute(self, code):
int_res['stderr'] = format_stderr(e)
return int_res

backup = deepcopy(self.ctx.stack)
backup = deepcopy(self.ctx)

try:
res = do_interpret(self.ctx, code_expr)
if res is None and len(self.ctx) > 0:
res = self.ctx.peek()

int_res['result'] = format_result(res)
int_res['stdout'] = format_stdout(self.ctx.stdout)
int_res['success'] = True
self.ctx.stdout.clear()
except MichelsonRuntimeError as e:
if self.debug:
raise e

int_res['stderr'] = format_stderr(e)
self.ctx.stack = backup
finally:
int_res['stdout'] = format_stdout(self.ctx.stdout)
self.ctx.stdout.clear()
self.ctx = backup
finally:
if self.debug:
print(int_res['stdout'])

if self.debug and int_res['result']:
print('RETURN: ')
pprint(int_res['result'])
print('RETURN: ' + pformat(int_res['result']))

return int_res
11 changes: 9 additions & 2 deletions pytezos/repl/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,10 @@ def get_int(val_expr):
return int(get_core_val(val_expr, core_type='int'))


def get_bool(val_expr):
return dispatch_prim_map(val_expr, {'True': True, 'False': False})


def get_bytes(val_expr):
return bytes.fromhex(get_core_val(val_expr, core_type='bytes'))

Expand Down Expand Up @@ -357,13 +361,16 @@ def parse_key_hash(val_expr, type_args):

@primitive('signature')
def parse_signature(val_expr, type_args):
return get_string(val_expr)
return dispatch_core_map(val_expr, {
'bytes': lambda x: encoding.parse_signature(bytes.fromhex(x)),
'string': lambda x: x
})


@primitive('chain_id')
def parse_chain_id(val_expr, type_args):
return dispatch_core_map(val_expr, {
'bytes': lambda x: encoding.base58_encode(bytes.fromhex(x), b'Net').decode(),
'bytes': lambda x: encoding.parse_chain_id(bytes.fromhex(x)),
'string': lambda x: x
})

Expand Down

0 comments on commit 5c92c24

Please sign in to comment.