merge with master
This commit is contained in:
@@ -16,8 +16,6 @@
|
||||
|
||||
//! Blockchain block.
|
||||
|
||||
#![cfg_attr(feature="dev", allow(ptr_arg))] // Because of &LastHashes -> &Vec<_>
|
||||
|
||||
use common::*;
|
||||
use engine::*;
|
||||
use state::*;
|
||||
@@ -76,11 +74,11 @@ pub struct BlockRefMut<'a> {
|
||||
/// Block header.
|
||||
pub header: &'a mut Header,
|
||||
/// Block transactions.
|
||||
pub transactions: &'a Vec<SignedTransaction>,
|
||||
pub transactions: &'a [SignedTransaction],
|
||||
/// Block uncles.
|
||||
pub uncles: &'a Vec<Header>,
|
||||
pub uncles: &'a [Header],
|
||||
/// Transaction receipts.
|
||||
pub receipts: &'a Vec<Receipt>,
|
||||
pub receipts: &'a [Receipt],
|
||||
/// State.
|
||||
pub state: &'a mut State,
|
||||
/// Traces.
|
||||
@@ -92,11 +90,11 @@ pub struct BlockRef<'a> {
|
||||
/// Block header.
|
||||
pub header: &'a Header,
|
||||
/// Block transactions.
|
||||
pub transactions: &'a Vec<SignedTransaction>,
|
||||
pub transactions: &'a [SignedTransaction],
|
||||
/// Block uncles.
|
||||
pub uncles: &'a Vec<Header>,
|
||||
pub uncles: &'a [Header],
|
||||
/// Transaction receipts.
|
||||
pub receipts: &'a Vec<Receipt>,
|
||||
pub receipts: &'a [Receipt],
|
||||
/// State.
|
||||
pub state: &'a State,
|
||||
/// Traces.
|
||||
@@ -152,16 +150,16 @@ pub trait IsBlock {
|
||||
fn state(&self) -> &State { &self.block().state }
|
||||
|
||||
/// Get all information on transactions in this block.
|
||||
fn transactions(&self) -> &Vec<SignedTransaction> { &self.block().base.transactions }
|
||||
fn transactions(&self) -> &[SignedTransaction] { &self.block().base.transactions }
|
||||
|
||||
/// Get all information on receipts in this block.
|
||||
fn receipts(&self) -> &Vec<Receipt> { &self.block().receipts }
|
||||
fn receipts(&self) -> &[Receipt] { &self.block().receipts }
|
||||
|
||||
/// Get all information concerning transaction tracing in this block.
|
||||
fn traces(&self) -> &Option<Vec<Trace>> { &self.block().traces }
|
||||
|
||||
/// Get all uncles in this block.
|
||||
fn uncles(&self) -> &Vec<Header> { &self.block().base.uncles }
|
||||
fn uncles(&self) -> &[Header] { &self.block().base.uncles }
|
||||
}
|
||||
|
||||
/// Trait for a object that has a state database.
|
||||
|
||||
@@ -426,7 +426,7 @@ impl Client {
|
||||
};
|
||||
|
||||
// Commit results
|
||||
let receipts = block.receipts().clone();
|
||||
let receipts = block.receipts().to_owned();
|
||||
let traces = From::from(block.traces().clone().unwrap_or_else(Vec::new));
|
||||
|
||||
// CHECK! I *think* this is fine, even if the state_root is equal to another
|
||||
|
||||
@@ -107,6 +107,9 @@ pub trait CostType: ops::Mul<Output=Self> + ops::Div<Output=Self> + ops::Add<Out
|
||||
fn overflow_add(self, other: Self) -> (Self, bool);
|
||||
/// Multiple with overflow
|
||||
fn overflow_mul(self, other: Self) -> (Self, bool);
|
||||
/// Single-step full multiplication and division: `self*other/div`
|
||||
/// Should not overflow on intermediate steps
|
||||
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool);
|
||||
}
|
||||
|
||||
impl CostType for U256 {
|
||||
@@ -129,6 +132,17 @@ impl CostType for U256 {
|
||||
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
||||
Uint::overflowing_mul(self, other)
|
||||
}
|
||||
|
||||
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool) {
|
||||
let x = self.full_mul(other);
|
||||
let (U512(parts), o) = Uint::overflowing_div(x, U512::from(div));
|
||||
let overflow = (parts[4] | parts[5] | parts[6] | parts[7]) > 0;
|
||||
|
||||
(
|
||||
U256([parts[0], parts[1], parts[2], parts[3]]),
|
||||
o | overflow
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl CostType for usize {
|
||||
@@ -154,6 +168,14 @@ impl CostType for usize {
|
||||
fn overflow_mul(self, other: Self) -> (Self, bool) {
|
||||
self.overflowing_mul(other)
|
||||
}
|
||||
|
||||
fn overflow_mul_div(self, other: Self, div: Self) -> (Self, bool) {
|
||||
let (c, o) = U128::from(self).overflowing_mul(U128::from(other));
|
||||
let (U128(parts), o1) = c.overflowing_div(U128::from(div));
|
||||
let result = parts[0] as usize;
|
||||
let overflow = o | o1 | (parts[1] > 0) | (parts[0] > result as u64);
|
||||
(result, overflow)
|
||||
}
|
||||
}
|
||||
|
||||
/// Evm interface
|
||||
@@ -164,3 +186,41 @@ pub trait Evm {
|
||||
/// to compute the final gas left.
|
||||
fn exec(&mut self, params: ActionParams, ext: &mut Ext) -> Result<GasLeft>;
|
||||
}
|
||||
|
||||
|
||||
#[test]
|
||||
fn should_calculate_overflow_mul_div_without_overflow() {
|
||||
// given
|
||||
let num = 10_000_000;
|
||||
|
||||
// when
|
||||
let (res1, o1) = U256::from(num).overflow_mul_div(U256::from(num), U256::from(num));
|
||||
let (res2, o2) = num.overflow_mul_div(num, num);
|
||||
|
||||
// then
|
||||
assert_eq!(res1, U256::from(num));
|
||||
assert!(!o1);
|
||||
assert_eq!(res2, num);
|
||||
assert!(!o2);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn should_calculate_overflow_mul_div_with_overflow() {
|
||||
// given
|
||||
let max = ::std::u64::MAX;
|
||||
let num1 = U256([max, max, max, max]);
|
||||
let num2 = ::std::usize::MAX;
|
||||
|
||||
// when
|
||||
let (res1, o1) = num1.overflow_mul_div(num1, num1 - U256::from(2));
|
||||
let (res2, o2) = num2.overflow_mul_div(num2, num2 - 2);
|
||||
|
||||
// then
|
||||
// (x+2)^2/x = (x^2 + 4x + 4)/x = x + 4 + 4/x ~ (MAX-2) + 4 + 0 = 1
|
||||
assert_eq!(res2, 1);
|
||||
assert!(o2);
|
||||
|
||||
assert_eq!(res1, U256::from(1));
|
||||
assert!(o1);
|
||||
}
|
||||
|
||||
|
||||
@@ -68,6 +68,9 @@ impl<Gas: CostType> Gasometer<Gas> {
|
||||
let default_gas = Gas::from(schedule.tier_step_gas[tier]);
|
||||
|
||||
let cost = match instruction {
|
||||
instructions::JUMPDEST => {
|
||||
InstructionCost::Gas(Gas::from(1))
|
||||
},
|
||||
instructions::SSTORE => {
|
||||
let address = H256::from(stack.peek(0));
|
||||
let newval = stack.peek(1);
|
||||
@@ -106,9 +109,6 @@ impl<Gas: CostType> Gasometer<Gas> {
|
||||
instructions::EXTCODECOPY => {
|
||||
InstructionCost::GasMemCopy(default_gas, try!(self.mem_needed(stack.peek(1), stack.peek(3))), try!(Gas::from_u256(*stack.peek(3))))
|
||||
},
|
||||
instructions::JUMPDEST => {
|
||||
InstructionCost::Gas(Gas::from(1))
|
||||
},
|
||||
instructions::LOG0...instructions::LOG4 => {
|
||||
let no_of_topics = instructions::get_log_topics(instruction);
|
||||
let log_gas = schedule.log_gas + schedule.log_topic_gas * no_of_topics;
|
||||
@@ -199,14 +199,12 @@ impl<Gas: CostType> Gasometer<Gas> {
|
||||
let s = mem_size >> 5;
|
||||
// s * memory_gas + s * s / quad_coeff_div
|
||||
let a = overflowing!(s.overflow_mul(Gas::from(schedule.memory_gas)));
|
||||
// We need to go to U512 to calculate s*s/quad_coeff_div
|
||||
let b = U512::from(s.as_u256()) * U512::from(s.as_u256()) / U512::from(schedule.quad_coeff_div);
|
||||
if b > U512::from(!U256::zero()) {
|
||||
Err(evm::Error::OutOfGas)
|
||||
} else {
|
||||
Ok(overflowing!(a.overflow_add(try!(Gas::from_u256(U256::from(b))))))
|
||||
}
|
||||
|
||||
// Calculate s*s/quad_coeff_div
|
||||
let b = overflowing!(s.overflow_mul_div(s, Gas::from(schedule.quad_coeff_div)));
|
||||
Ok(overflowing!(a.overflow_add(b)))
|
||||
};
|
||||
|
||||
let current_mem_size = Gas::from(current_mem_size);
|
||||
let req_mem_size_rounded = (overflowing!(mem_size.overflow_add(Gas::from(31 as usize))) >> 5) << 5;
|
||||
|
||||
|
||||
@@ -143,7 +143,7 @@ impl Header {
|
||||
/// Get the difficulty field of the header.
|
||||
pub fn difficulty(&self) -> &U256 { &self.difficulty }
|
||||
/// Get the seal field of the header.
|
||||
pub fn seal(&self) -> &Vec<Bytes> { &self.seal }
|
||||
pub fn seal(&self) -> &[Bytes] { &self.seal }
|
||||
|
||||
// TODO: seal_at, set_seal_at &c.
|
||||
|
||||
|
||||
@@ -98,7 +98,7 @@ const V7_VERSION_KEY: &'static [u8] = &[ b'j', b'v', b'e', b'r', 0, 0, 0, 0, 0,
|
||||
const DB_VERSION: u32 = 0x203;
|
||||
const PADDING : [u8; 10] = [0u8; 10];
|
||||
|
||||
/// Version for OverlayRecent database.
|
||||
/// Version for `OverlayRecent` database.
|
||||
/// more involved than the archive version because of journaling.
|
||||
#[derive(Default)]
|
||||
pub struct OverlayRecentV7 {
|
||||
@@ -258,4 +258,4 @@ impl Migration for OverlayRecentV7 {
|
||||
try!(self.walk_journal(source));
|
||||
self.migrate_journal(source, batch, dest)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -665,7 +665,7 @@ impl MinerService for Miner {
|
||||
};
|
||||
match (&self.options.pending_set, sealing_set) {
|
||||
(&PendingSet::AlwaysQueue, _) | (&PendingSet::SealingOrElseQueue, None) => queue.top_transactions(),
|
||||
(_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().clone()),
|
||||
(_, sealing) => sealing.map_or_else(Vec::new, |s| s.transactions().to_owned()),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -702,7 +702,7 @@ impl MinerService for Miner {
|
||||
.iter()
|
||||
.map(|t| t.hash());
|
||||
|
||||
let receipts = pending.receipts().clone().into_iter();
|
||||
let receipts = pending.receipts().iter().cloned();
|
||||
|
||||
hashes.zip(receipts).collect()
|
||||
},
|
||||
|
||||
@@ -143,7 +143,7 @@ impl Spec {
|
||||
}
|
||||
|
||||
/// Get the known knodes of the network in enode format.
|
||||
pub fn nodes(&self) -> &Vec<String> { &self.nodes }
|
||||
pub fn nodes(&self) -> &[String] { &self.nodes }
|
||||
|
||||
/// Get the configured Network ID.
|
||||
pub fn network_id(&self) -> U256 { self.params.network_id }
|
||||
|
||||
Reference in New Issue
Block a user