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

Provide general-purpose wide arithmetic (128-bit) API #246

Open
michaeldiamant opened this issue Mar 14, 2022 · 3 comments
Open

Provide general-purpose wide arithmetic (128-bit) API #246

michaeldiamant opened this issue Mar 14, 2022 · 3 comments
Assignees
Labels
new-feature-request Feature request that needs triage Team Scytale

Comments

@michaeldiamant
Copy link
Contributor

Problem

PyTeal's ergonomics for wide arithmetic opcodes (addw, mulw, divw, divmodw, expw) is limited. Limitation examples:

  • No general-purpose way exists to confirm the result of wide arithmetic operations fits into 64 bits. While possible for PyTeal developers to implement, it'd be less error prone PyTeal provided a 1st class facility.
    • Here's an example implementing the logic for a special purpose use case:
      combine = TealSimpleBlock(
      [
      TealOp(self, Op.divmodw),
      TealOp(self, Op.pop), # pop remainder low word
      TealOp(self, Op.pop), # pop remainder high word
      TealOp(self, Op.swap), # swap quotient high and low words
      TealOp(self, Op.logic_not),
      TealOp(self, Op.assert_), # assert quotient high word is 0
      # end with quotient low word remaining on the stack
      ]
  • No general-purpose abstraction exists for wide arithmetic operations. Consequently, PyTeal developers must hand roll abstractions (e.g. add two 128-bit ints). It feels like a common abstraction can be provided to minimize sources of error and promote application consistency.

Solution

  • Define wide arithmetic abstraction (e.g. WideUint128) with these APIs for 64-bit and 128-bit operations:
    • +
    • -
    • *
    • /
    • mod
    • exp
  • Consider interactions with existing abstractions (e.g. WideRatio).
  • Update user guide docs.

Background context:

Dependencies

N/A

Urgency

TBD

@huybuidac
Copy link

This is "must have" feature, there is no way to implement "farm/amm/swap..." contract without this.

Can anyone please take care it? :(

@PabloLION
Copy link
Contributor

PabloLION commented Sep 23, 2022

Edited and reposted in #541

I self-assign here if no one is working on it. Here are some questions about Operator Overloading.

I'm thinking about adding the operator overload like what you did in for 64-bit uint (AKA, uint8). Two things I'm not sure on this topic:

between two uint16

Currently I have two ideas for this. Below, all ABCD are uint8 and XYZ are fake uint16, like 2-tuples of uint8:

  1. Create a new type of uint16 wrapping up the two uint, the API would be X = Uint16(A,B); Y = Uint16(C,D); X*Y where X*Y is overloaded to Mulw(X,Y). Alternative names for Uint16 are: Wide
  2. use a tuple of 2 uint8, the call method would be like Mulw( (A,B),(C,D) ), or (A,B)*(C,D). Tho I think if python accepts this kind of op overload.
  3. I don't recommend this one: use mulw for in all types, replacing mul.

between uint8 and uint16

Also I'm not sure if I should add a overload for arithmetics between uint16 and uint8, like X*A->Y, A+X->Y etc.

Any ideas? TIA.

@PabloLION
Copy link
Contributor

@barnjamin I made a PR #543 and a partial PR #544. But I don't have to finish the latter recently, so I unassign myself for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new-feature-request Feature request that needs triage Team Scytale
Projects
None yet
Development

No branches or pull requests

3 participants