Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Integration of EIP1962 precompile #10874

Closed
wants to merge 5 commits into from
Closed

Integration of EIP1962 precompile #10874

wants to merge 5 commits into from

Conversation

shamatar
Copy link

@shamatar shamatar commented Jul 11, 2019

This PR incorporates reference implementation for EIP1962 into Parity client.

Due to the structure of EIP functionality this integration delegates most of the work to the implementation:

  • Implementation has a pricer that may return an error on malformed inputs or computationally insane parameters, in this case U256::max_value() is returned
  • Implementation will do the parsing and input validation (and was fuzzy-tested), in this case error is cast into client-specific one

@parity-cla-bot
Copy link

It looks like @shamatar signed our Contributor License Agreement. 👍

Many thanks,

Parity Technologies CLA Bot

@jam10o-new jam10o-new added the A0-pleasereview 🤓 Pull request needs code review. label Jul 11, 2019
@jam10o-new jam10o-new added this to the 2.7 milestone Jul 11, 2019
@jam10o-new jam10o-new added F8-enhancement 🎊 An additional feature request. M4-core ⛓ Core client code / Rust. B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. and removed B7-releasenotes 📜 Changes should be mentioned in the release notes of the next minor version release. labels Jul 11, 2019
@@ -548,14 +572,39 @@ impl Bn128Pairing {
}
}

impl Implementation for EIP1962 {
/// Can fail in many cases, so leave it for an implementation
Copy link
Collaborator

Choose a reason for hiding this comment

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

No need for a doc-comment here. Also: I'm not sure what "…so leave it for an implementation" means, can you clarify?

Copy link
Author

Choose a reason for hiding this comment

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

Parity client implements gas metering for BN128 and Modexp itself. In case of EIP 1962 gas estimating function is implemented as a part of the crate, so this implementation just calls such implementation. For a doc-comment - sure, I'll add one.

impl Implementation for EIP1962 {
/// Can fail in many cases, so leave it for an implementation
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
let result = eth_pairings::public_interface::API::run(&input);
Copy link
Collaborator

Choose a reason for hiding this comment

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

eth_pairings::public_interface::API is an odd sequence of names, why not just eth_pairings::run? I mean, if it's callable from the outside it's part of the api and part of the public interface so it seems tautological to repeat "api" and "public interface".

fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
let result = eth_pairings::public_interface::API::run(&input);
if result.is_err() {
trace!("EIP1962 error: {:?}", result.err().expect("is error"));
Copy link
Collaborator

Choose a reason for hiding this comment

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

Better to use error! here.

let result = eth_pairings::public_interface::API::run(&input);
if result.is_err() {
trace!("EIP1962 error: {:?}", result.err().expect("is error"));
return Err("Precompile call was unsuccessful");
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you include the actual error in the string?

Copy link
Author

Choose a reason for hiding this comment

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

Sure, I was not sure if it would be handy

trace!("EIP1962 error: {:?}", result.err().expect("is error"));
return Err("Precompile call was unsuccessful");
}
let result: Vec<u8> = result.expect("some result");
Copy link
Collaborator

Choose a reason for hiding this comment

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

All expects should motivate the reason why it is safe to unwrap, e.g. "we just checked if is_err so we know it's ok; qed"

return Err("Precompile call returned no data");
}
if result.len() == 1 {
// manually made BE of Uint256(1)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
// manually made BE of Uint256(1)
// manually make BE of Uint256(1)

buf[31] = result[0];
output.write(0, &buf);
} else {
output.write(0, &result[..]);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Is this guaranteed to be of a certain length (32 bytes?)? If so, can you do &result[..32] here?

Copy link
Author

Choose a reason for hiding this comment

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

A single byte is returned iff a pairing operation is performed, so I manually put this byte into last byte of 32 bytes buffer to simulate serialization of U256. In case of other operations returned length is not equal to one, so I write directly to the output.

assert_eq!(f.cost(&input[..]), expected_cost.into());
}

// test for a valid return value for some BLS12 test vector
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can you add the source for this test vector to the comment?

@dvdplm dvdplm requested a review from sorpaas August 12, 2019 15:00
impl Implementation for EIP1962 {
/// Can fail in many cases, so leave it for an implementation
fn execute(&self, input: &[u8], output: &mut BytesRef) -> Result<(), &'static str> {
let result = eth_pairings::public_interface::API::run(&input);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
let result = eth_pairings::public_interface::API::run(&input);
let result = eth_pairings::public_interface::API::run(&input).map_err(|e| ...insert anything here you want to display e...)?;

@sorpaas sorpaas mentioned this pull request Aug 15, 2019
6 tasks
@openethereum openethereum deleted a comment from shamatar Mar 24, 2020
@openethereum openethereum deleted a comment from parity-cla-bot Mar 24, 2020
@shamatar shamatar closed this Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A0-pleasereview 🤓 Pull request needs code review. F8-enhancement 🎊 An additional feature request. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants