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

Fix some broken opcodes due to JS number issues #168

Merged
merged 9 commits into from
Aug 14, 2017
Merged

Conversation

axic
Copy link
Member

@axic axic commented Aug 11, 2017

Part of #167. Fixes #169.

@axic
Copy link
Member Author

axic commented Aug 12, 2017

@cdetrio @jwasinger @holgerd77 dare to review this? :)

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.

Generally looks good to me, please give a short feedback to the gtn operator and the jumpIsValid() function questions.

@@ -3,6 +3,7 @@ const utils = require('ethereumjs-util')

module.exports = {
getBlock: function (n, cb) {
// FIXME: this will fail on block numbers >53 bits
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 not breaking for me when invoking with numbers > Number.MAX_SAFE_INTEGER, but refactoring this won't hurt and is definitely cleaner.

Copy link
Member Author

Choose a reason for hiding this comment

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

After upgrading ethereumjs-util it likely will throw an exception.

a = utils.bufferToInt(a)
return Buffer.from([!a])
a = new BN(a)
return Buffer.from([a.isZero()])
},
Copy link
Member

Choose a reason for hiding this comment

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

Look good.

pos = pos.toNumber()
word = utils.setLengthLeft(word, 32)

return utils.intToBuffer(word[pos])
},
Copy link
Member

Choose a reason for hiding this comment

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

Looks good as well, went through line-by-line and looked for equivalency of both versions and tested with some real-world parameters.

pos = pos.toNumber()
loaded = runState.callData.slice(pos, pos + 32)
loaded = loaded.length ? loaded : Buffer.from([0])
}

Copy link
Member

Choose a reason for hiding this comment

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

Look good, this first check of callData length seems to be cleaner for me as well. Wondered if the gtn for the pos > runState.callData.length comparison should be used instead of the simple > operator though it seems that this is working as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, it shouldn't work with > 😕

Javascript...

Copy link
Member Author

Choose a reason for hiding this comment

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

Fixed.

Copy link
Member Author

@axic axic Aug 14, 2017

Choose a reason for hiding this comment

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

console.log(new BN(0) > 42) => false
console.log(new BN(44) > 42) => true

Ah yeah I remember, Javascript calls parseInt(object.toString()) if it is not a Number, i.e. it will do what we don't want.

Copy link
Member

Choose a reason for hiding this comment

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

Hmmm, to just change this would have been the cleaner solution in my regard, but ok.

Copy link
Member Author

Choose a reason for hiding this comment

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

It was changed, just explained why it did "work" or more likely why the tests don't have a good coverage.


// block lookups must be within the past 256 blocks
if (diff > 256 || diff <= 0) {
if (diff.gtn(256) || diff.lten(0)) {
cb(null, Buffer.from([0]))
return
}
Copy link
Member

Choose a reason for hiding this comment

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

Looks good.

}

runState.programCounter = dest
}
},
Copy link
Member

Choose a reason for hiding this comment

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

Why not put the extra code length check here in the jumpIsValid logic?

Copy link
Member

Choose a reason for hiding this comment

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

Phew, this is so much better readable now. Looks good as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, that is the edge case of having JUMPI as the last instruction in the code. Need to check the YP.

Copy link
Member Author

Choose a reason for hiding this comment

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

It seems that results in a STOP and not invalid jump. Will double check.

trap(ERROR.INVALID_JUMP + ' at ' + describeLocation(runState))
}

dest = dest.toNumber()
Copy link
Member

Choose a reason for hiding this comment

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

This looks good otherwise.

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.

BLOCKHASH is broken
4 participants