Skip to content

eth/types: add Num superclass and Hex, Dec, Bin descendants#76

Closed
mculp wants to merge 39 commits into
q9f:mainfrom
mculp:add-num-type
Closed

eth/types: add Num superclass and Hex, Dec, Bin descendants#76
mculp wants to merge 39 commits into
q9f:mainfrom
mculp:add-num-type

Conversation

@mculp
Copy link
Copy Markdown
Contributor

@mculp mculp commented Apr 25, 2022

Copy link
Copy Markdown
Owner

@q9f q9f left a comment

Choose a reason for hiding this comment

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

Thank you. I already had some opinions and left some comments.

Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
Comment thread lib/eth/types/faceted_numeric.rb Outdated
@mculp mculp changed the title Add FacetedNumeric type Add Num May 7, 2022
@mculp mculp requested a review from q9f May 7, 2022 05:28
@mculp mculp marked this pull request as ready for review May 7, 2022 05:30
q9f
q9f previously requested changes May 9, 2022
Copy link
Copy Markdown
Owner

@q9f q9f left a comment

Choose a reason for hiding this comment

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

Thank you, Matt.

I'm not very happy with how Ruby handles types. Therefore, I think using refinements should be avoided.

If we want to use the Num type throughout the library, we should handle all conversions internally in the Num class privately and only expose some getters for the different formats.

What do you think?

@codecov-commenter
Copy link
Copy Markdown

codecov-commenter commented May 10, 2022

Codecov Report

Merging #76 (ee140a5) into main (7926fc4) will decrease coverage by 0.01%.
The diff coverage is 99.45%.

@@            Coverage Diff             @@
##             main      #76      +/-   ##
==========================================
- Coverage   99.74%   99.73%   -0.02%     
==========================================
  Files          67       76       +9     
  Lines        3923     4108     +185     
==========================================
+ Hits         3913     4097     +184     
- Misses         10       11       +1     
Impacted Files Coverage Δ
spec/eth/types/num_spec.rb 93.75% <93.75%> (ø)
lib/eth.rb 100.00% <100.00%> (ø)
lib/eth/constant.rb 100.00% <100.00%> (ø)
lib/eth/types/bin.rb 100.00% <100.00%> (ø)
lib/eth/types/dec.rb 100.00% <100.00%> (ø)
lib/eth/types/hex.rb 100.00% <100.00%> (ø)
lib/eth/types/num.rb 100.00% <100.00%> (ø)
spec/eth/constant_spec.rb 100.00% <100.00%> (ø)
spec/eth/types/bin_spec.rb 100.00% <100.00%> (ø)
spec/eth/types/dec_spec.rb 100.00% <100.00%> (ø)
... and 2 more

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented May 11, 2022

Thank you, Matt.

I'm not very happy with how Ruby handles types. Therefore, I think using refinements should be avoided.

If we want to use the Num type throughout the library, we should handle all conversions internally in the Num class privately and only expose some getters for the different formats.

What do you think?

Just curious, what do you see as the issue with using refinements? A refinement is scoped to the file in which it is used. It's opt-in, file-by-file. So, as this PR stands, the only class that can see the changes to the String/Integer classes is Num. I was thinking we could add further conversions in the refinement (to_keccak, for example) and other classes could opt-in to using the refinement as they want.

If refinements are out, I think the next-best solution would be to subclass Num w/ Hex, Dec, Bin:

class Num
  attr_reader :hex, :dec, :bin
  
  def initialize(input = nil)
    generate_number
  end
  
  def to_bytes
    bin
  end
  
  def to_i
    dec
  end
  
  def to_hex
    hex
  end
end

class Hex < Num
  def initialize(input)
    @hex = input.delete_prefix('0x')
    @dec = hex.to_i(16)
    @bin = hex.scan(/../).map(&:hex).pack('C*').b
  end
end

Hex['0xasdfa'].to_bytes

I was going back and forth with this and the refinement solution; we can't do a straight port from Crystal because you can't define multiple constructors in Ruby. I did see you added a gem to do something like that, but the "multiple constructors" are actually just builder/factory methods if I understand it correctly. i.e. we'd have to do something like this: Num.from_hex('0xafsdfasdf') (we want something short and sweet) and there'd be a bunch of nested branching logic, which is typically avoided if possible in Ruby.

Now that I've looked at the code I typed above, using inheritance would probably be the most idiomatic solution out of the 3.

What do you think?

(btw, I'm not trying to be difficult. I'm just trying to solve this the simplest and most idiomatic way)

@q9f
Copy link
Copy Markdown
Owner

q9f commented May 11, 2022

Now that I've looked at the code I typed above, using inheritance would probably be the most idiomatic solution out of the 3.

Yes, I love it. I'm not too concerned about the implications of the refinements, it's more about the style.

Sorry for being so pedantic. I think, your last suggestion most simple and clean approach.

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented May 11, 2022

Now that I've looked at the code I typed above, using inheritance would probably be the most idiomatic solution out of the 3.

Yes, I love it. I'm not too concerned about the implications of the refinements, it's more about the style.

Sorry for being so pedantic. I think, your last suggestion most simple and clean approach.

Awesome! What do you think if the files live in eth/types/... but then have their constants hoisted to Eth like Eth::Num = Eth::Types::Num, which would be shortened to Num in practice because everything is within the Eth namespace.

My original concern with the subclass approach was that I didn't want to pollute the top-level directory with a bunch of files, so I just rolled with the refinement since it's all technically self contained in Num.

@mculp mculp changed the title Add Num eth/types: add Num superclass and Hex, Dec, Bin descendants May 13, 2022
@q9f q9f added the enhancement New feature or request label May 13, 2022
@q9f
Copy link
Copy Markdown
Owner

q9f commented Jun 10, 2022

This is looking good so far, do you need a hand to finish this off? :)

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented Jul 28, 2022

hey @q9f so sorry for the delay, I took a month vacation. Will finish this asap.

q9f and others added 9 commits July 27, 2022 22:27
* spec: add signer contract for eip-1271

* eth/client: implement is_valid_signature

* eth/client: document is_valid_signature

* docs: update readme
* eth/contract: allow creating from file, abi, bin

* eth/client: refactor contract code

* Update lib/eth/contract.rb

Co-authored-by: Yuta Kurotaki <yuta.kurotaki@gmail.com>

* Update lib/eth/contract.rb

Co-authored-by: Yuta Kurotaki <yuta.kurotaki@gmail.com>

* spec: deploy ens and call it

* spec: fix client spec for eip 1271

* docs: fix readme for contracts

* docs: fix readme for contracts

* spec: fix jsonrpc error code

* spec: fix coverage

* spec: fix coverage

* eth/contract: apply @mculp's suggestions

Co-authored-by: Matt Culpepper <mculp@users.noreply.github.com>

* eth/contract: apply @mculp's suggestions

Co-authored-by: Matt Culpepper <mculp@users.noreply.github.com>

Co-authored-by: Yuta Kurotaki <yuta.kurotaki@gmail.com>
Co-authored-by: Matt Culpepper <mculp@users.noreply.github.com>
* eth/client: fix account requirement for client.call()

* eth/client: allow passing key to call()
* ci: add weekly dependency checks

* ci: add weekly dependency checks
Bumps [github/codeql-action](https://github.com/github/codeql-action) from 1 to 2.
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](github/codeql-action@v1...v2)

---
updated-dependencies:
- dependency-name: github/codeql-action
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/checkout](https://github.com/actions/checkout) from 2 to 3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v2...v3)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
kurotaky and others added 15 commits July 27, 2022 22:27
* Fix Eth::Abi::DecodingError in call method

* Fix argument address
* Add missing def_delegator for constructor_inputs

* Enable passing in constructor to deploy contracts

* Call greeter function with params

* Update greeter.sol

Co-authored-by: Bea <bea@Beas-MacBook-Pro-2.local>
Co-authored-by: Yuta Kurotaki <yuta.kurotaki@gmail.com>
Co-authored-by: Cuong Pham <harry88pham@gmail.com>
* eth/abi: allow parsing numerics from string inputs

* sepc: run rufo
* Revert "eth/abi: allow parsing numerics from string inputs (q9f#112)"

This reverts commit bb640c7.

* eth/abi: raise error if numeric comes as string
* Add gas limit override option for contract deployments

* Formatting :donut:

* Add gas limit override to other contract calls. Add some tests.
* eth/abi: support dynamic array encoding

* eth/abi: support dynamic array encoding

* Update spec/eth/abi_spec.rb

Co-authored-by: Afri <58883403+q9f@users.noreply.github.com>

* fix rspec

* format abi_spec

Co-authored-by: Afri <58883403+q9f@users.noreply.github.com>
Bumps [JamesIves/github-pages-deploy-action](https://github.com/JamesIves/github-pages-deploy-action) from 4.3.3 to 4.3.4.
- [Release notes](https://github.com/JamesIves/github-pages-deploy-action/releases)
- [Commits](JamesIves/github-pages-deploy-action@v4.3.3...v4.3.4)

---
updated-dependencies:
- dependency-name: JamesIves/github-pages-deploy-action
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented Aug 1, 2022

hey @q9f I made some updates, let me know what you think.

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented Aug 4, 2022

Is the CI broken? It says it's missing a token

@q9f
Copy link
Copy Markdown
Owner

q9f commented Sep 26, 2022

Can you run rufo on the code? I will review asap.

Also, can you rebase on main branch? You pulled in a lot of commits unrelated to this work.

You can ignore the missing token issue on CI. It should be temporary.

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented Sep 27, 2022

@q9f I updated this with Rufo.

@q9f
Copy link
Copy Markdown
Owner

q9f commented Sep 27, 2022

one test is failing, please check the CI

@mculp
Copy link
Copy Markdown
Contributor Author

mculp commented Sep 29, 2022

Going down a rabbit hole with this one test.

@q9f I should've asked this question a long time ago, but I noticed in the Crystal Num, it was essentially 3 types: Hex, Decimal, and an array of ASCII chars.

Do we want to do that here instead of this bytestring stuff I'm trying to do? The reason I chose a bytestring instead of an array of ascii ordinals is because the Keccak lib dumps/reads a bytestring.

Now:

    # @example Instantiate a Hex object
    #   Hex('0xdeadbeef')
    #     => #<Eth::Types::Hex:0x00007f8dcb102330
    #       @input="0xdeadbeef",
    #       @hex="deadbeef",
    #       @bin="\xDE\xAD\xBE\xEF",
    #       @dec=3735928559>

Would be much easier to deal with, but may not provide the same utility/helpfulness:

    # @example Instantiate a Hex object
    #   Hex('0xdeadbeef')
    #     => #<Eth::Types::Hex:0x00007f8dcb102330
    #       @input="0xdeadbeef",
    #       @hex="deadbeef",
    #       @bin=[51, 55, 51, 53, 57, 50, 56, 53, 53, 57],
    #       @dec=3735928559>

What do you think? This PR is starting to feel like a monkey on my back.

@q9f
Copy link
Copy Markdown
Owner

q9f commented Oct 27, 2022

Haha, sorry for that. Please be creative, it's really not a high priority.

@q9f
Copy link
Copy Markdown
Owner

q9f commented Dec 21, 2022

Let's bench this for now

@q9f q9f closed this Dec 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants