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

Keep the stack items as an instance of bn.js #159

Merged
merged 4 commits into from
Jan 30, 2018
Merged

Conversation

axic
Copy link
Member

@axic axic commented Jul 28, 2017

Fixes #38. Depends on #167, #168 and #174.

@axic axic changed the title Keep the stack items as an instance of bn.js [WIP] Keep the stack items as an instance of bn.js Jul 28, 2017
@axic axic force-pushed the feature/bn-as-stack branch from 22f8d4d to 906834c Compare July 28, 2017 18:44
@axic axic force-pushed the feature/bn-as-stack branch 4 times, most recently from 2189881 to d68b535 Compare August 10, 2017 23:28
@axic
Copy link
Member Author

axic commented Aug 11, 2017

Down to:

# tests 2412
# pass  2323
# fail  89

@axic axic force-pushed the feature/bn-as-stack branch 6 times, most recently from 60265f7 to ce14b30 Compare August 15, 2017 00:01
@axic axic force-pushed the feature/bn-as-stack branch from ce14b30 to cd76a34 Compare December 9, 2017 19:34
@axic
Copy link
Member Author

axic commented Dec 9, 2017

Rebased this locally over #174, will push once that is merged.

@axic axic force-pushed the feature/bn-as-stack branch 3 times, most recently from dc3f1e0 to 3f43220 Compare December 10, 2017 03:18
@axic axic changed the title [WIP] Keep the stack items as an instance of bn.js Keep the stack items as an instance of bn.js Dec 10, 2017
@axic axic force-pushed the feature/bn-as-stack branch from 3f43220 to e6a67a3 Compare December 10, 2017 03:23
@axic
Copy link
Member Author

axic commented Dec 10, 2017

@jwasinger I think this should work now too. Rebased and fixed some bugs.

@axic axic force-pushed the feature/bn-as-stack branch from e6a67a3 to a9f7b72 Compare December 12, 2017 05:24
@axic
Copy link
Member Author

axic commented Dec 12, 2017

Fixed returndatasize, returndatacopy, jumpi and log. Push may be broken.

@jwasinger jwasinger self-assigned this Dec 15, 2017
@axic axic force-pushed the feature/bn-as-stack branch from dac24b2 to a82a5d3 Compare December 17, 2017 21:56
@holgerd77
Copy link
Member

Two other fixes, this is now down to 0 failures:

1..4646
# tests 4646
# pass  4646

# ok

😄

Let's wait with merging at least until Monday though, maybe someone wants to have another one-step-back view on this.

@holgerd77
Copy link
Member

Short speed comparison (on local MacBook Air) running the state tests:

feature/bn-as-stack branch: 4:04 min
master branch: 4:08 min

Hmm, seems this was more for easier reading than for speed though.

lib/opFns.js Outdated
// NOTE: we're using a 'trick' here to get the least significant byte
byte = byte.toArrayLike(Buffer, 'le', 1)
byte = byte.toArrayLike(Buffer, 'be', 32)
byte = byte.slice(byte.length - 1)
Copy link
Member Author

Choose a reason for hiding this comment

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

Can you extract a case from the tests where this caused an issue? I'd like to figure out what is the actual reason.

Copy link
Member

Choose a reason for hiding this comment

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

node tests/tester.js -s --test='randomStatetest237' --jsontrace

In Node console:

const utils = require('ethereumjs-util')
const BN = utils.BN
var bn = new BN('fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe', 'hex')
bn.toArrayLike(Buffer, 'le', 1)

gives

Error: byte array longer than desired length
    at assert (/Users/hdrewes/Documents/DEV/EthereumJS/ethereumjs-vm/node_modules/bn.js/lib/bn.js:6:21)
    at BN.toArrayLike (/Users/hdrewes/Documents/DEV/EthereumJS/ethereumjs-vm/node_modules/bn.js/lib/bn.js:527:5)
    at repl:1:4
    at ContextifyScript.Script.runInThisContext (vm.js:44:33)
    at REPLServer.defaultEval (repl.js:239:29)
    at bound (domain.js:301:14)
    at REPLServer.runBound [as eval] (domain.js:314:12)
    at REPLServer.onLine (repl.js:440:10)
    at emitOne (events.js:120:20)
    at REPLServer.emit (events.js:210:7)

Copy link
Member

Choose a reason for hiding this comment

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

Actually this is failing for every Buffer with length > 1, e.g. also for var bn = new BN('fffe', 'hex').

Copy link
Member Author

@axic axic Jan 26, 2018

Choose a reason for hiding this comment

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

Ah true, didn't in the end added the truncation support to bn.js.

Copy link
Member Author

@axic axic Jan 26, 2018

Choose a reason for hiding this comment

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

Could still do Buffer.from(bn.andln(0xff))

@axic
Copy link
Member Author

axic commented Jan 26, 2018

@holgerd77 that optimisation works - do you want to double check it?

@holgerd77
Copy link
Member

Should we do a minor release after this is merged?

@axic: I have to admit I'm not getting your new trick. 😎 😸

@axic
Copy link
Member Author

axic commented Jan 26, 2018

.andln is bitwise AND, so basically we get the lowest 1 byte (with 0xff) out of BN. But .andln, unlike any other bn.js function, doesn't return a new BN instance, rather a Javascript number.

Sure, we can make a release.

lib/opFns.js Outdated
},
ISZERO: function (a, runState) {
return new BN(a.isZero())
return new BN(a.isZero() ? 1 : 0)
Copy link
Member Author

Choose a reason for hiding this comment

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

I think these make sense, but were there actually causing an issue?

Copy link
Member

Choose a reason for hiding this comment

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

Yes, creating a BN instance from true is actually resulting in another value initialization than with 1.

> new BN(true)
<BN: 7d0e>
> new BN(1)
<BN: 1>

Not sure if this is an error in bn.js. I find this more explicit and better to read anyway.

Copy link
Member Author

Choose a reason for hiding this comment

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

True, we are till using an outdated bn.js version which treated everything as a number and did random things. Finally a recent version would throw an error of invalid digit for given number base :)

lib/opFns.js Outdated
},
EQ: function (a, b, runState) {
return new BN(a.cmp(b) === 0)
return new BN(a.cmp(b) === 0 ? 1 : 0)
Copy link
Member Author

Choose a reason for hiding this comment

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

Oh this code was done way before the higher level helpers were added to bn.js. We could use a.eq(b) here and above.

Copy link
Member Author

Choose a reason for hiding this comment

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

Created a new PR for this.

@axic
Copy link
Member Author

axic commented Jan 30, 2018

@holgerd77 are you OK with squashing down the MSTORE8 changes and merging?

@holgerd77
Copy link
Member

@axic Is it possible (and did you mean that variant) squashing the MSTORE8 commit into the first one 888ed25 "Keep the stack items as BN.js instances"? Or would you (should I?) just squash the commit into the previous one? (or is there another possible way to proceed here?)

@axic
Copy link
Member Author

axic commented Jan 30, 2018

@holgerd77 I'll do the squashing of that one into the original, but leaving every other fix intact.

Just asking if you are happy with the last solution?

@holgerd77
Copy link
Member

Yes. Just curious how you will do that (squashing into the original, skipping the in-between commits) Not seeing anything for that in interactive rebase command selection. Any trick?

@axic
Copy link
Member Author

axic commented Jan 30, 2018

Try interactive rebase: git rebase -i HEAD~6 (offers interactive rebasing of the last 6 commits).

@holgerd77
Copy link
Member

Ah, this note "These lines can be re-ordered;" from the rebase instructions was the missing part for me, didn't know that.

@axic
Copy link
Member Author

axic commented Jan 30, 2018

@holgerd77 ok to accept?

@holgerd77
Copy link
Member

Yes (the "Yes" from above was also already answering this. Sorry maybe too hidden. :-)).

Copy link
Member

@holgerd77 holgerd77 left a comment

Choose a reason for hiding this comment

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

Looks good, can be merged when tests pass.

@axic axic merged commit 0fba8e3 into master Jan 30, 2018
@axic axic removed the in progress label Jan 30, 2018
@axic axic deleted the feature/bn-as-stack branch January 30, 2018 12:46
@axic
Copy link
Member Author

axic commented Jan 30, 2018

Hmm, seems this was more for easier reading than for speed though.

I think there should be a more measurable speed increase on running contracts doing arithmetics. See some of @gcolvin's benchmarks for rc5, division and exponentiation.

holgerd77 added a commit that referenced this pull request May 26, 2023
ci: separate browser test to own actions run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Speed optim: store bn.js instances as stack elements
4 participants