Skip to content

Commit

Permalink
Fix repeated logging with topics
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidKnott committed Oct 7, 2017
1 parent a2e9e7c commit cb3ce65
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 21 deletions.
31 changes: 30 additions & 1 deletion tests/parser/features/test_logging.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ def foo():
assert c.translator.decode_event(logs.topics, logs.data) == {'arg1': b'bar', 'arg2': b'home', 'arg3': '0x'+c.address.hex(), '_event_type': b'MyLog'}


def test_logging_the_same_event_multiple_times_with_topics():
loggy_code = """
MyLog: __log__({arg1: indexed(num), arg2: indexed(address)})
def foo():
log.MyLog(1, self)
log.MyLog(1, self)
def bar():
log.MyLog(1, self)
log.MyLog(1, self)
"""

c = get_contract(loggy_code)
c.foo()
c.bar()
logs = s.head_state.receipts[-1].logs[-1]
event_id = u.bytes_to_int(u.sha3(bytes('MyLog(int128,address)', 'utf-8')))
# Event id is always the first topic
assert logs.topics[0] == event_id
# Event id is calculated correctly
assert c.translator.event_data[event_id]
# Event abi is created correctly
assert c.translator.event_data[event_id] == {'types': ['int128','address'], 'name': 'MyLog', 'names': ['arg1','arg2'], 'indexed': [True,True], 'anonymous': False}
# Event is decoded correctly
assert c.translator.decode_event(logs.topics, logs.data) == {'_event_type': b'MyLog', 'arg1': 1, 'arg2': '0x' + c.address.hex()}


def test_event_logging_cannot_have_more_than_three_topics():
loggy_code = """
MyLog: __log__({arg1: indexed(bytes <= 3), arg2: indexed(bytes <= 4), arg3: indexed(address), arg4: indexed(num)})
Expand Down Expand Up @@ -110,7 +138,8 @@ def test_event_loggging_with_fixed_array_data():
def foo():
log.MyLog([1,2], [block.timestamp, block.timestamp+1, block.timestamp+2], [[1,2],[1,2]])
# """
log.MyLog([1,2], [block.timestamp, block.timestamp+1, block.timestamp+2], [[1,2],[1,2]])
"""

c = get_contract(loggy_code)
c.foo()
Expand Down
34 changes: 16 additions & 18 deletions viper/parser/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -954,23 +954,21 @@ def parse_stmt(stmt, context):
return Stmt(stmt, context).lll_node


def pack_logging_topics(event, args, context):
topics = [event.event_id]
stored_topics = ['seq']
def pack_logging_topics(event_id, args, topics_types, context):
topics = [event_id]
topics_count = 1
for pos, is_indexed in enumerate(event.indexed_list):
if is_indexed:
typ = event.args.pop(pos + 1 - topics_count).typ
arg = args.pop(pos + 1 - topics_count)
topics_count += 1
if isinstance(arg, ast.Str):
stored_topics.append(parse_value_expr(arg, context))
topics.append(['mload', stored_topics[-1].to_list()[-1][-1][-1] + 32])
else:
input = parse_value_expr(arg, context)
input = base_type_conversion(input, input.typ, typ)
topics.append(input)
return topics, stored_topics, event, args
stored_topics = ['seq']
for pos, typ in enumerate(topics_types):
arg = args[pos]
topics_count += 1
if isinstance(arg, ast.Str):
stored_topics.append(parse_value_expr(arg, context))
topics.append(['mload', stored_topics[-1].to_list()[-1][-1][-1] + 32])
else:
input = parse_value_expr(arg, context)
input = base_type_conversion(input, input.typ, typ)
topics.append(input)
return topics, stored_topics


def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder):
Expand Down Expand Up @@ -998,13 +996,13 @@ def pack_args_by_32(holder, maxlen, arg, typ, context, placeholder):


# Pack logging data arguments
def pack_logging_data(signature, args, context):
def pack_logging_data(types, args, context):
# Checks to see if there's any data
if not args:
return ['seq'], 0, 0
holder = ['seq']
maxlen = len(args) * 32
for i, (arg, typ) in enumerate(zip(args, [arg.typ for arg in signature.args])):
for i, (arg, typ) in enumerate(zip(args, types)):
holder, maxlen = pack_args_by_32(holder, maxlen, arg, typ, context, context.new_placeholder(BaseType(32)))
return holder, maxlen, holder[1].to_list()[1][0]

Expand Down
13 changes: 11 additions & 2 deletions viper/parser/stmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,17 @@ def call(self):
if self.stmt.func.attr not in self.context.sigs['self']:
raise VariableDeclarationException("Event not declared yet: %s" % self.stmt.func.attr)
event = self.context.sigs['self'][self.stmt.func.attr]
topics, stored_topics, event, data = pack_logging_topics(event, self.stmt.args, self.context)
inargs, inargsize, inarg_start = pack_logging_data(event, data, self.context)
topics_types, topics = [], []
data_types, data = [], []
for pos, is_indexed in enumerate(event.indexed_list):
if is_indexed:
topics_types.append(event.args[pos].typ)
topics.append(self.stmt.args[pos])
else:
data_types.append(event.args[pos].typ)
data.append(self.stmt.args[pos])
topics, stored_topics = pack_logging_topics(event.event_id, topics, topics_types, self.context)
inargs, inargsize, inarg_start = pack_logging_data(data_types, data, self.context)
return LLLnode.from_list(['seq', inargs, stored_topics, ["log" + str(len(topics)), inarg_start, inargsize] + topics], typ=None, pos=getpos(self.stmt))
else:
raise StructureException("Unsupported operator: %r" % ast.dump(self.stmt), self.stmt)
Expand Down

0 comments on commit cb3ce65

Please sign in to comment.