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

Commit

Permalink
Additional validity requirements
Browse files Browse the repository at this point in the history
  • Loading branch information
arkpar committed Apr 4, 2017
1 parent d82afbe commit 195dbeb
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 24 deletions.
2 changes: 1 addition & 1 deletion ethcore/res/ethereum/tests
Submodule tests updated 5857 files
5 changes: 5 additions & 0 deletions ethcore/src/evm/schedule.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,11 @@ impl Schedule {
}
}

/// Schedule for the Metropolis of the Ethereum main net.
pub fn new_metropolis() -> Schedule {
Self::new_post_eip150(24576, true, true, true, true)
}

fn new(efcd: bool, hdc: bool, tcg: usize) -> Schedule {
Schedule {
exceptional_failed_code_deposit: efcd,
Expand Down
24 changes: 15 additions & 9 deletions ethcore/src/json_tests/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,35 +18,37 @@ use super::test_common::*;
use evm;
use ethjson;
use rlp::UntrustedRlp;
use transaction::{Action, UnverifiedTransaction};
use ethstore::ethkey::public_to_address;
use transaction::{Action, UnverifiedTransaction, SignedTransaction};

fn do_json_test(json_data: &[u8]) -> Vec<String> {
let tests = ethjson::transaction::Test::load(json_data).unwrap();
let mut failed = Vec::new();
let old_schedule = evm::Schedule::new_frontier();
let new_schedule = evm::Schedule::new_homestead();
let frontier_schedule = evm::Schedule::new_frontier();
let homestead_schedule = evm::Schedule::new_homestead();
let metropolis_schedule = evm::Schedule::new_metropolis();
for (name, test) in tests.into_iter() {
let mut fail_unless = |cond: bool, title: &str| if !cond { failed.push(name.clone()); println!("Transaction failed: {:?}: {:?}", name, title); };

let number: Option<u64> = test.block_number.map(Into::into);
let schedule = match number {
None => &old_schedule,
Some(x) if x < 1_150_000 => &old_schedule,
Some(_) => &new_schedule
None => &frontier_schedule,
Some(x) if x < 1_150_000 => &frontier_schedule,
Some(x) if x < 3_000_000 => &homestead_schedule,
Some(_) => &metropolis_schedule
};
let allow_network_id_of_one = number.map_or(false, |n| n >= 2_675_000);
let allow_unsigned = number.map_or(false, |n| n >= 3_000_000);

let rlp: Vec<u8> = test.rlp.into();
let res = UntrustedRlp::new(&rlp)
.as_val()
.map_err(From::from)
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one));
.and_then(|t: UnverifiedTransaction| t.validate(schedule, schedule.have_delegate_call, allow_network_id_of_one, allow_unsigned));

fail_unless(test.transaction.is_none() == res.is_err(), "Validity different");
if let (Some(tx), Some(sender)) = (test.transaction, test.sender) {
let t = res.unwrap();
fail_unless(public_to_address(&t.recover_public().unwrap()) == sender.into(), "sender mismatch");
fail_unless(SignedTransaction::new(t.clone()).unwrap().sender() == sender.into(), "sender mismatch");
let is_acceptable_network_id = match t.network_id() {
None => true,
Some(1) if allow_network_id_of_one => true,
Expand Down Expand Up @@ -84,3 +86,7 @@ declare_test!{TransactionTests_Homestead_ttTransactionTestEip155VitaliksTests, "
declare_test!{TransactionTests_EIP155_ttTransactionTest, "TransactionTests/EIP155/ttTransactionTest"}
declare_test!{TransactionTests_EIP155_ttTransactionTestEip155VitaliksTests, "TransactionTests/EIP155/ttTransactionTestEip155VitaliksTests"}
declare_test!{TransactionTests_EIP155_ttTransactionTestVRule, "TransactionTests/EIP155/ttTransactionTestVRule"}

declare_test!{TransactionTests_Metropolis_ttMetropolisTest, "TransactionTests/Metropolis/ttMetropolisTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTest, "TransactionTests/Metropolis/ttTransactionTest"}
declare_test!{TransactionTests_Metropolis_ttTransactionTestZeroSig, "TransactionTests/Metropolis/ttTransactionTestZeroSig"}
25 changes: 11 additions & 14 deletions ethcore/src/types/transaction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,7 @@ impl UnverifiedTransaction {
/// The network ID, or `None` if this is a global transaction.
pub fn network_id(&self) -> Option<u64> {
match self.v {
v if self.is_unsigned() => Some(v),
v if v > 36 => Some((v - 35) / 2),
_ => None,
}
Expand Down Expand Up @@ -348,29 +349,25 @@ impl UnverifiedTransaction {
// TODO: consider use in block validation.
#[cfg(test)]
#[cfg(feature = "json-tests")]
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool) -> Result<UnverifiedTransaction, Error> {
if require_low && !self.signature().is_low_s() {
return Err(EthkeyError::InvalidSignature.into())
}
match self.network_id() {
None => {},
Some(1) if allow_network_id_of_one => {},
_ => return Err(TransactionError::InvalidNetworkId.into()),
pub fn validate(self, schedule: &Schedule, require_low: bool, allow_network_id_of_one: bool, allow_empty_signature: bool) -> Result<UnverifiedTransaction, Error> {
let chain_id = if allow_network_id_of_one { Some(1) } else { None };
self.verify_basic(require_low, chain_id, allow_empty_signature)?;
if !allow_empty_signature || !self.is_unsigned() {
self.recover_public()?;
}
self.recover_public()?;
if self.gas < U256::from(self.gas_required(&schedule)) {
Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
} else {
Ok(self)
return Err(TransactionError::InvalidGasLimit(::util::OutOfBounds{min: Some(U256::from(self.gas_required(&schedule))), max: None, found: self.gas}).into())
}
Ok(self)
}

/// Verify basic signature params. Does not attempt sender recovery.
pub fn verify_basic(&self, check_low_s: bool, chain_id: Option<u64>, allow_empty_signature: bool) -> Result<(), Error> {
if check_low_s && !allow_empty_signature {
if check_low_s && !(allow_empty_signature && self.is_unsigned()) {
self.check_low_s()?;
}
if !allow_empty_signature && self.is_unsigned() {
// EIP-86: Transactions of this form MUST have gasprice = 0, nonce = 0, value = 0, and do NOT increment the nonce of account 0.
if allow_empty_signature && self.is_unsigned() && !(self.gas_price.is_zero() && self.value.is_zero() && self.nonce.is_zero()) {
return Err(EthkeyError::InvalidSignature.into())
}
match (self.network_id(), chain_id) {
Expand Down

0 comments on commit 195dbeb

Please sign in to comment.