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

Num256 with natural expressions. #355

Closed
wants to merge 2 commits into from

Conversation

jacqueswww
Copy link
Contributor

@jacqueswww jacqueswww commented Sep 20, 2017

- What I did

Added support for num256 to be evaluated without using builtin num256_xxx functions.

- How I did it

  • I started looking at basic evaluations off the following expressions:
def _num256_sub(x: num256, y: num256) -> num256:
    return x - y
  • And the compiler didn't understand num256 without the num256_xxx functions.
  • Currently num256 -> decimal -> num operations are not handled yet but I felt this could be a seperate PR instead.

- How to verify it

Check the test, one can also evaluate the LLL output with the following example (or similar):

def multiply(x: num256, y: num256) -> num256:
    return x * y


def multiply_func(x: num256, y: num256) -> num256:
    return num256_mul(x, y)

- Description for the changelog

Allows evaluating of basic arithmetic expressions using uint256 and uint256.

- Cute Animal Picture

Copy link
Member

@fubuloubu fubuloubu left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks pretty good, encompasses all the changes I would expect

if o.typ.typ == 'num':
return LLLnode.from_list(['clamp', ['mload', MINNUM_POS], o, ['mload', MAXNUM_POS]], typ=o.typ, pos=getpos(expr))
elif o.typ.typ == 'decimal':
return LLLnode.from_list(['clamp', ['mload', MINDECIMAL_POS], o, ['mload', MAXDECIMAL_POS]], typ=o.typ, pos=getpos(expr))
elif o.typ.typ == 'num256':
return o
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can return o directly here because there is no need for an overflow check? Is that correct?

Copy link
Contributor Author

@jacqueswww jacqueswww Sep 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fubuloubu yes that was my understanding, ie. the full 32byte has been occupied by a single variable, therefore can't overflow. But I could be wrong ? I worked from the LLL output of num256_ functions - they definitely don't have any sort of clamping - If we do require it, let me know and I will add it :)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jacqueswww I believe you should add clamping so that this test case results in TransactionFailed (right now it passes). Clamping here is necessary because it checks user input (which can result in a number more than 2**256-1).
"""

def test_num_256_overflow():
    num256_code = """
def _num256_mul(x: num256, y: num256) -> num256:
    return num256_mul(x, y)

c = get_contract_with_gas_estimation(num256_code)
x = 2 ** 256 - 1
assert c._num256_mul(x, x) == 1

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect @DavidKnott!

Copy link
Contributor Author

@jacqueswww jacqueswww Sep 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff thanks for the info, will add soonest ;)

@@ -627,6 +627,8 @@ def parse_expr(expr, context):
new_unit = combine_units(left.typ.unit, right.typ.unit)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually about L623 above. Does it make sense not to implement cross-type operations? I believe it might for num256|decimal, as we might have data loss there, but num|num256 can occur fine withouth data loss (implicit conversion of num to num256).

Same below L656 (in updated file) for division. Does it make sense not to have cross-type division? I'm leaning towards yes, but discuss.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fubuloubu sure I was going to do cross-type operations as a seperate PR. For the time being the compiler will throw an error with any type of cross-type operation. If you prefer I can do num | num256 as part of this PR/branch ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think doing it as a separate PR would work best. There are some subtle considerations that I think warrant a second PR. I'll add an issue to remind ourselves of this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool thanks :) 👍

@@ -645,6 +647,8 @@ def parse_expr(expr, context):
new_unit = combine_units(left.typ.unit, right.typ.unit, div=True)
if rtyp == 'num':
o = LLLnode.from_list(['sdiv', left, ['clamp_nonzero', right]], typ=BaseType(ltyp, new_unit), pos=getpos(expr))
elif ltyp == rtyp == 'num256':
o = LLLnode.from_list(['div', left, right], typ=BaseType('num256', new_unit), pos=getpos(expr))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's a potential for data loss here. I'm not sure if there's a way to avoid it (such as above for num, which also has potential data loss). Discuss.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And by data loss, I mean decimal point flooring (or does it round? @DavidKnott )

@jacqueswww
Copy link
Contributor Author

jacqueswww commented Sep 29, 2017

Closing as this is to be replaced by a specific type or decorator that casts (and clamps) to num.

@jacqueswww jacqueswww closed this Sep 29, 2017
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

Successfully merging this pull request may close these issues.

3 participants