Skip to content
This repository was archived by the owner on Nov 6, 2020. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions ethcore/builtin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ edition = "2018"

[dependencies]
bn = { git = "https://github.com/paritytech/bn", default-features = false }
common-types = { path = "../types" }
ethereum-types = "0.8.0"
ethjson = { path = "../../json" }
ethkey = { path = "../../accounts/ethkey" }
Expand Down
81 changes: 44 additions & 37 deletions ethcore/builtin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@

use std::{
cmp::{max, min},
convert::TryFrom,
io::{self, Read, Cursor},
mem::size_of,
};

use bn;
use byteorder::{BigEndian, LittleEndian, ReadBytesExt};
use common_types::errors::EthcoreError;
use ethereum_types::{H256, U256};
use ethjson;
use ethkey::{Signature, recover as ec_recover};
Expand Down Expand Up @@ -215,8 +217,10 @@ impl Builtin {
}
}

impl From<ethjson::spec::Builtin> for Builtin {
fn from(b: ethjson::spec::Builtin) -> Self {
impl TryFrom<ethjson::spec::Builtin> for Builtin {
type Error = EthcoreError;

fn try_from(b: ethjson::spec::Builtin) -> Result<Self, Self::Error> {
let pricer: Box<dyn Pricer> = match b.pricing {
ethjson::spec::Pricing::Blake2F { gas_per_round } => {
Box::new(gas_per_round)
Expand Down Expand Up @@ -259,17 +263,18 @@ impl From<ethjson::spec::Builtin> for Builtin {
}
};

Builtin {
let native = ethereum_builtin(&b.name)?;
Ok(Builtin {
pricer,
native: ethereum_builtin(&b.name),
native,
activate_at: b.activate_at.map_or(0, Into::into),
}
})
}
}

/// Ethereum built-in factory.
fn ethereum_builtin(name: &str) -> Box<dyn Implementation> {
match name {
fn ethereum_builtin(name: &str) -> Result<Box<dyn Implementation>, EthcoreError> {
let implementation = match name {
"identity" => Box::new(Identity) as Box<dyn Implementation>,
"ecrecover" => Box::new(EcRecover) as Box<dyn Implementation>,
"sha256" => Box::new(Sha256) as Box<dyn Implementation>,
Expand All @@ -279,8 +284,9 @@ fn ethereum_builtin(name: &str) -> Box<dyn Implementation> {
"alt_bn128_mul" => Box::new(Bn128Mul) as Box<dyn Implementation>,
"alt_bn128_pairing" => Box::new(Bn128Pairing) as Box<dyn Implementation>,
"blake2_f" => Box::new(Blake2F) as Box<dyn Implementation>,
_ => panic!("invalid builtin name: {}", name),
}
_ => return Err(EthcoreError::Msg(format!("invalid builtin name: {}", name))),
};
Ok(implementation)
}

// Ethereum builtins:
Expand Down Expand Up @@ -679,6 +685,7 @@ impl Bn128Pairing {

#[cfg(test)]
mod tests {
use std::convert::TryFrom;
use ethereum_types::U256;
use ethjson::uint::Uint;
use num::{BigUint, Zero, One};
Expand All @@ -690,7 +697,7 @@ mod tests {
fn blake2f_cost() {
let f = Builtin {
pricer: Box::new(123),
native: ethereum_builtin("blake2_f"),
native: ethereum_builtin("blake2_f").expect("known builtin"),
activate_at: 0,
};
// 5 rounds
Expand All @@ -703,7 +710,7 @@ mod tests {

#[test]
fn blake2_f_is_err_on_invalid_length() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 1 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-1
let input = hex!("00000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let mut out = [0u8; 64];
Expand All @@ -715,7 +722,7 @@ mod tests {

#[test]
fn blake2_f_is_err_on_invalid_length_2() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 2 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-2
let input = hex!("000000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let mut out = [0u8; 64];
Expand All @@ -727,7 +734,7 @@ mod tests {

#[test]
fn blake2_f_is_err_on_bad_finalization_flag() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 3 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-3
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000002");
let mut out = [0u8; 64];
Expand All @@ -739,7 +746,7 @@ mod tests {

#[test]
fn blake2_f_zero_rounds_is_ok_test_vector_4() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 4 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-4
let input = hex!("0000000048c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("08c9bcf367e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d282e6ad7f520e511f6c3e2b8c68059b9442be0454267ce079217e1319cde05b");
Expand All @@ -750,7 +757,7 @@ mod tests {

#[test]
fn blake2_f_test_vector_5() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 5 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-5
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("ba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923");
Expand All @@ -761,7 +768,7 @@ mod tests {

#[test]
fn blake2_f_test_vector_6() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 6 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-6
let input = hex!("0000000c48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000");
let expected = hex!("75ab69d3190a562c51aef8d88f1c2775876944407270c42c9844252c26d2875298743e7f6d5ea2f2d3e8d226039cd31b4e426ac4f2d3d666a610c2116fde4735");
Expand All @@ -772,7 +779,7 @@ mod tests {

#[test]
fn blake2_f_test_vector_7() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 7 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-7
let input = hex!("0000000148c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
let expected = hex!("b63a380cb2897d521994a85234ee2c181b5f844d2c624c002677e9703449d2fba551b3a8333bcdf5f2f7e08993d53923de3d64fcc68c034e717b9293fed7a421");
Expand All @@ -784,7 +791,7 @@ mod tests {
#[ignore]
#[test]
fn blake2_f_test_vector_8() {
let blake2 = ethereum_builtin("blake2_f");
let blake2 = ethereum_builtin("blake2_f").expect("known builtin");
// Test vector 8 and expected output from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-152.md#test-vector-8
// Note this test is slow, 4294967295/0xffffffff rounds take a while.
let input = hex!("ffffffff48c9bdf267e6096a3ba7ca8485ae67bb2bf894fe72f36e3cf1361d5f3af54fa5d182e6ad7f520e511f6c3e2b8c68059b6bbd41fbabd9831f79217e1319cde05b61626300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000001");
Expand Down Expand Up @@ -829,7 +836,7 @@ mod tests {

#[test]
fn identity() {
let f = ethereum_builtin("identity");
let f = ethereum_builtin("identity").expect("known builtin");

let i = [0u8, 1, 2, 3];

Expand All @@ -849,7 +856,7 @@ mod tests {

#[test]
fn sha256() {
let f = ethereum_builtin("sha256");
let f = ethereum_builtin("sha256").expect("known builtin");

let i = [0u8; 0];

Expand All @@ -872,7 +879,7 @@ mod tests {

#[test]
fn ripemd160() {
let f = ethereum_builtin("ripemd160");
let f = ethereum_builtin("ripemd160").expect("known builtin");

let i = [0u8; 0];

Expand All @@ -891,7 +898,7 @@ mod tests {

#[test]
fn ecrecover() {
let f = ethereum_builtin("ecrecover");
let f = ethereum_builtin("ecrecover").expect("known builtin");

let i = hex!("47173285a8d7341e5e972fc677286384f802f8ef42a5ec5f03bbfa254cb01fad000000000000000000000000000000000000000000000000000000000000001b650acf9d3f5f0a2c799776a1254355d5f4061762a237396a99a0e0e3fc2bcd6729514a0dacb2e623ac4abd157cb18163ff942280db4d5caad66ddf941ba12e03");

Expand Down Expand Up @@ -944,7 +951,7 @@ mod tests {

let f = Builtin {
pricer: Box::new(ModexpPricer { divisor: 20 }),
native: ethereum_builtin("modexp"),
native: ethereum_builtin("modexp").expect("known builtin"),
activate_at: 0,
};

Expand Down Expand Up @@ -1055,7 +1062,7 @@ mod tests {

let f = Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("alt_bn128_add"),
native: ethereum_builtin("alt_bn128_add").expect("known builtin"),
activate_at: 0,
};

Expand Down Expand Up @@ -1114,7 +1121,7 @@ mod tests {

let f = Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("alt_bn128_mul"),
native: ethereum_builtin("alt_bn128_mul").expect("known builtin"),
activate_at: 0,
};

Expand Down Expand Up @@ -1154,7 +1161,7 @@ mod tests {
fn builtin_pairing() -> Builtin {
Builtin {
pricer: Box::new(Linear { base: 0, word: 0 }),
native: ethereum_builtin("alt_bn128_pairing"),
native: ethereum_builtin("alt_bn128_pairing").expect("known builtin"),
activate_at: 0,
}
}
Expand Down Expand Up @@ -1226,15 +1233,15 @@ mod tests {
#[test]
#[should_panic]
fn from_unknown_linear() {
let _ = ethereum_builtin("foo");
let _ = ethereum_builtin("foo").unwrap();
}

#[test]
fn is_active() {
let pricer = Box::new(Linear { base: 10, word: 20} );
let b = Builtin {
pricer: pricer as Box<dyn Pricer>,
native: ethereum_builtin("identity"),
native: ethereum_builtin("identity").expect("known builtin"),
activate_at: 100_000,
};

Expand All @@ -1248,7 +1255,7 @@ mod tests {
let pricer = Box::new(Linear { base: 10, word: 20 });
let b = Builtin {
pricer: pricer as Box<dyn Pricer>,
native: ethereum_builtin("identity"),
native: ethereum_builtin("identity").expect("known builtin"),
activate_at: 1,
};

Expand All @@ -1265,15 +1272,15 @@ mod tests {

#[test]
fn from_json() {
let b = Builtin::from(ethjson::spec::Builtin {
let b = Builtin::try_from(ethjson::spec::Builtin {
name: "identity".to_owned(),
pricing: ethjson::spec::Pricing::Linear(ethjson::spec::Linear {
base: 10,
word: 20,
}),
activate_at: None,
eip1108_transition: None,
});
}).expect("known builtin");

assert_eq!(b.cost(&[0; 0], 0), U256::from(10));
assert_eq!(b.cost(&[0; 1], 0), U256::from(30));
Expand All @@ -1288,7 +1295,7 @@ mod tests {

#[test]
fn bn128_pairing_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
let b = Builtin::try_from(ethjson::spec::Builtin {
name: "alt_bn128_pairing".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128Pairing(ethjson::spec::builtin::AltBn128Pairing {
base: 100_000,
Expand All @@ -1298,39 +1305,39 @@ mod tests {
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
}).expect("known builtin");

assert_eq!(b.cost(&[0; 192 * 3], 10), U256::from(340_000), "80 000 * 3 + 100 000 == 340 000");
assert_eq!(b.cost(&[0; 192 * 7], 20), U256::from(283_000), "34 000 * 7 + 45 000 == 283 000");
}

#[test]
fn bn128_add_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
let b = Builtin::try_from(ethjson::spec::Builtin {
name: "alt_bn128_add".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations {
price: 500,
eip1108_transition_price: 150,
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
}).expect("known builtin");

assert_eq!(b.cost(&[0; 192], 10), U256::from(500));
assert_eq!(b.cost(&[0; 10], 20), U256::from(150), "after istanbul hardfork gas cost for add should be 150");
}

#[test]
fn bn128_mul_eip1108_transition() {
let b = Builtin::from(ethjson::spec::Builtin {
let b = Builtin::try_from(ethjson::spec::Builtin {
name: "alt_bn128_mul".to_owned(),
pricing: ethjson::spec::Pricing::AltBn128ConstOperations(ethjson::spec::builtin::AltBn128ConstOperations {
price: 40_000,
eip1108_transition_price: 6000,
}),
activate_at: Some(Uint(U256::from(10))),
eip1108_transition: Some(Uint(U256::from(20))),
});
}).expect("known builtin");

assert_eq!(b.cost(&[0; 192], 10), U256::from(40_000));
assert_eq!(b.cost(&[0; 10], 20), U256::from(6_000), "after istanbul hardfork gas cost for mul should be 6 000");
Expand Down
4 changes: 3 additions & 1 deletion ethcore/machine/src/test_helpers.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,16 @@

//! Provide facilities to create `Machine` instances for testing various networks.

use std::convert::TryFrom;
use common_types::engines::params::CommonParams;
use ethcore_builtin::Builtin;
use ethjson;
use crate::Machine;

pub fn load_machine(reader: &[u8]) -> Machine {
let spec = ethjson::spec::Spec::load(reader).expect("chain spec is invalid");

let builtins = spec.accounts.builtins().into_iter().map(|p| (p.0.into(), From::from(p.1))).collect();
let builtins = spec.accounts.builtins().into_iter().map(|p| (p.0.into(), Builtin::try_from(p.1).expect("chain spec is invalid"))).collect();
Comment thread
niklasad1 marked this conversation as resolved.
let params = CommonParams::from(spec.params);

if let ethjson::spec::Engine::Ethash(ref ethash) = spec.engine {
Expand Down
Loading