Merge pull request #7197 from paritytech/td-beta-backports
Beta backports
This commit is contained in:
commit
03b1e9d8ba
@ -23,7 +23,9 @@
|
||||
]
|
||||
},
|
||||
"validateScoreTransition": 1000000,
|
||||
"validateStepTransition": 1500000
|
||||
"validateStepTransition": 1500000,
|
||||
"maximumUncleCountTransition": 10000000,
|
||||
"maximumUncleCount": 2
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 9a1fcbf0d4e73bea437577e807bc38c7ba243d80
|
||||
Subproject commit d6185ea16eaba7ff685c069c2064819f9549c4d7
|
@ -380,8 +380,13 @@ impl<'x> OpenBlock<'x> {
|
||||
/// NOTE Will check chain constraints and the uncle number but will NOT check
|
||||
/// that the header itself is actually valid.
|
||||
pub fn push_uncle(&mut self, valid_uncle_header: Header) -> Result<(), BlockError> {
|
||||
if self.block.uncles.len() + 1 > self.engine.maximum_uncle_count() {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{min: None, max: Some(self.engine.maximum_uncle_count()), found: self.block.uncles.len() + 1}));
|
||||
let max_uncles = self.engine.maximum_uncle_count(self.block.header().number());
|
||||
if self.block.uncles.len() + 1 > max_uncles {
|
||||
return Err(BlockError::TooManyUncles(OutOfBounds{
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: self.block.uncles.len() + 1,
|
||||
}));
|
||||
}
|
||||
// TODO: check number
|
||||
// TODO: check not a direct ancestor (use last_hashes for that)
|
||||
|
@ -1230,12 +1230,12 @@ impl BlockChainClient for Client {
|
||||
}
|
||||
|
||||
fn estimate_gas(&self, t: &SignedTransaction, block: BlockId) -> Result<U256, CallError> {
|
||||
const UPPER_CEILING: u64 = 1_000_000_000_000u64;
|
||||
let (mut upper, env_info) = {
|
||||
let (mut upper, max_upper, env_info) = {
|
||||
let mut env_info = self.env_info(block).ok_or(CallError::StatePruned)?;
|
||||
let initial_upper = env_info.gas_limit;
|
||||
env_info.gas_limit = UPPER_CEILING.into();
|
||||
(initial_upper, env_info)
|
||||
let init = env_info.gas_limit;
|
||||
let max = init * U256::from(10);
|
||||
env_info.gas_limit = max;
|
||||
(init, max, env_info)
|
||||
};
|
||||
|
||||
// that's just a copy of the state.
|
||||
@ -1256,9 +1256,7 @@ impl BlockChainClient for Client {
|
||||
};
|
||||
|
||||
if !cond(upper)? {
|
||||
// impossible at block gas limit - try `UPPER_CEILING` instead.
|
||||
// TODO: consider raising limit by powers of two.
|
||||
upper = UPPER_CEILING.into();
|
||||
upper = max_upper;
|
||||
if !cond(upper)? {
|
||||
trace!(target: "estimate_gas", "estimate_gas failed with {}", upper);
|
||||
let err = ExecutionError::Internal(format!("Requires higher than upper limit of {}", upper));
|
||||
@ -1871,7 +1869,7 @@ impl MiningBlockChainClient for Client {
|
||||
.find_uncle_headers(&h, engine.maximum_uncle_age())
|
||||
.unwrap_or_else(Vec::new)
|
||||
.into_iter()
|
||||
.take(engine.maximum_uncle_count())
|
||||
.take(engine.maximum_uncle_count(open_block.header().number()))
|
||||
.foreach(|h| {
|
||||
open_block.push_uncle(h).expect("pushing maximum_uncle_count;
|
||||
open_block was just created;
|
||||
@ -1886,7 +1884,7 @@ impl MiningBlockChainClient for Client {
|
||||
fn reopen_block(&self, block: ClosedBlock) -> OpenBlock {
|
||||
let engine = &*self.engine;
|
||||
let mut block = block.reopen(engine);
|
||||
let max_uncles = engine.maximum_uncle_count();
|
||||
let max_uncles = engine.maximum_uncle_count(block.header().number());
|
||||
if block.uncles().len() < max_uncles {
|
||||
let chain = self.chain.read();
|
||||
let h = chain.best_block_hash();
|
||||
|
@ -65,6 +65,10 @@ pub struct AuthorityRoundParams {
|
||||
pub immediate_transitions: bool,
|
||||
/// Block reward in base units.
|
||||
pub block_reward: U256,
|
||||
/// Number of accepted uncles transition block.
|
||||
pub maximum_uncle_count_transition: u64,
|
||||
/// Number of accepted uncles.
|
||||
pub maximum_uncle_count: usize,
|
||||
}
|
||||
|
||||
impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
@ -77,6 +81,8 @@ impl From<ethjson::spec::AuthorityRoundParams> for AuthorityRoundParams {
|
||||
validate_step_transition: p.validate_step_transition.map_or(0, Into::into),
|
||||
immediate_transitions: p.immediate_transitions.unwrap_or(false),
|
||||
block_reward: p.block_reward.map_or_else(Default::default, Into::into),
|
||||
maximum_uncle_count_transition: p.maximum_uncle_count_transition.map_or(0, Into::into),
|
||||
maximum_uncle_count: p.maximum_uncle_count.map_or(0, Into::into),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -218,6 +224,8 @@ pub struct AuthorityRound {
|
||||
epoch_manager: Mutex<EpochManager>,
|
||||
immediate_transitions: bool,
|
||||
block_reward: U256,
|
||||
maximum_uncle_count_transition: u64,
|
||||
maximum_uncle_count: usize,
|
||||
machine: EthereumMachine,
|
||||
}
|
||||
|
||||
@ -365,6 +373,8 @@ impl AuthorityRound {
|
||||
epoch_manager: Mutex::new(EpochManager::blank()),
|
||||
immediate_transitions: our_params.immediate_transitions,
|
||||
block_reward: our_params.block_reward,
|
||||
maximum_uncle_count_transition: our_params.maximum_uncle_count_transition,
|
||||
maximum_uncle_count: our_params.maximum_uncle_count,
|
||||
machine: machine,
|
||||
});
|
||||
|
||||
@ -436,6 +446,15 @@ impl Engine<EthereumMachine> for AuthorityRound {
|
||||
]
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, block: BlockNumber) -> usize {
|
||||
if block >= self.maximum_uncle_count_transition {
|
||||
self.maximum_uncle_count
|
||||
} else {
|
||||
// fallback to default value
|
||||
2
|
||||
}
|
||||
}
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
// Chain scoring: total weight is sqrt(U256::max_value())*height - step
|
||||
let new_difficulty = U256::from(U128::max_value()) + header_step(parent).expect("Header has been verified; qed").into() - self.step.load().into();
|
||||
@ -949,6 +968,8 @@ mod tests {
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 0,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
@ -976,4 +997,31 @@ mod tests {
|
||||
assert!(aura.verify_block_family(&header, &parent_header).is_ok());
|
||||
assert_eq!(last_benign.load(AtomicOrdering::SeqCst), 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_uncles_transition() {
|
||||
let last_benign = Arc::new(AtomicUsize::new(0));
|
||||
let params = AuthorityRoundParams {
|
||||
step_duration: Default::default(),
|
||||
start_step: Some(1),
|
||||
validators: Box::new(TestSet::new(Default::default(), last_benign.clone())),
|
||||
validate_score_transition: 0,
|
||||
validate_step_transition: 0,
|
||||
immediate_transitions: true,
|
||||
maximum_uncle_count_transition: 1,
|
||||
maximum_uncle_count: 0,
|
||||
block_reward: Default::default(),
|
||||
};
|
||||
|
||||
let aura = {
|
||||
let mut c_params = ::spec::CommonParams::default();
|
||||
c_params.gas_limit_bound_divisor = 5.into();
|
||||
let machine = ::machine::EthereumMachine::regular(c_params, Default::default());
|
||||
AuthorityRound::new(params, machine).unwrap()
|
||||
};
|
||||
|
||||
assert_eq!(aura.maximum_uncle_count(0), 2);
|
||||
assert_eq!(aura.maximum_uncle_count(1), 0);
|
||||
assert_eq!(aura.maximum_uncle_count(100), 0);
|
||||
}
|
||||
}
|
||||
|
@ -192,7 +192,8 @@ pub trait Engine<M: Machine>: Sync + Send {
|
||||
fn extra_info(&self, _header: &M::Header) -> BTreeMap<String, String> { BTreeMap::new() }
|
||||
|
||||
/// Maximum number of uncles a block is allowed to declare.
|
||||
fn maximum_uncle_count(&self) -> usize { 2 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
/// The number of generations back that uncles can be.
|
||||
fn maximum_uncle_age(&self) -> usize { 6 }
|
||||
|
||||
@ -363,7 +364,7 @@ pub trait EthEngine: Engine<::machine::EthereumMachine> {
|
||||
}
|
||||
|
||||
/// The nonce with which accounts begin at given block.
|
||||
fn account_start_nonce(&self, block: u64) -> U256 {
|
||||
fn account_start_nonce(&self, block: BlockNumber) -> U256 {
|
||||
self.machine().account_start_nonce(block)
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
use bigint::prelude::U256;
|
||||
use engines::Engine;
|
||||
use header::BlockNumber;
|
||||
use parity_machine::{Header, LiveBlock, WithBalances};
|
||||
|
||||
/// Params for a null engine.
|
||||
@ -95,6 +96,8 @@ impl<M: WithBalances> Engine<M> for NullEngine<M> {
|
||||
self.machine.note_rewards(block, &[(author, result_block_reward)], &uncle_rewards)
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn verify_local_seal(&self, _header: &M::Header) -> Result<(), M::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
@ -450,7 +450,7 @@ impl Engine<EthereumMachine> for Tendermint {
|
||||
|
||||
fn machine(&self) -> &EthereumMachine { &self.machine }
|
||||
|
||||
fn maximum_uncle_count(&self) -> usize { 0 }
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 0 }
|
||||
|
||||
fn maximum_uncle_age(&self) -> usize { 0 }
|
||||
|
||||
|
@ -26,7 +26,7 @@ use util::Address;
|
||||
use unexpected::{OutOfBounds, Mismatch};
|
||||
use block::*;
|
||||
use error::{BlockError, Error};
|
||||
use header::Header;
|
||||
use header::{Header, BlockNumber};
|
||||
use engines::{self, Engine};
|
||||
use ethjson;
|
||||
use rlp::{self, UntrustedRlp};
|
||||
@ -181,6 +181,8 @@ impl Engine<EthereumMachine> for Arc<Ethash> {
|
||||
}
|
||||
}
|
||||
|
||||
fn maximum_uncle_count(&self, _block: BlockNumber) -> usize { 2 }
|
||||
|
||||
fn populate_from_parent(&self, header: &mut Header, parent: &Header) {
|
||||
let difficulty = self.calculate_difficulty(header, parent);
|
||||
header.set_difficulty(difficulty);
|
||||
@ -447,9 +449,12 @@ fn ecip1017_eras_block_reward(era_rounds: u64, mut reward: U256, block_number:u6
|
||||
} else {
|
||||
block_number / era_rounds
|
||||
};
|
||||
let mut divi = U256::from(1);
|
||||
for _ in 0..eras {
|
||||
reward = reward / U256::from(5) * U256::from(4);
|
||||
reward = reward * U256::from(4);
|
||||
divi = divi * U256::from(5);
|
||||
}
|
||||
reward = reward / divi;
|
||||
(eras, reward)
|
||||
}
|
||||
|
||||
@ -515,6 +520,11 @@ mod tests {
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(15, eras);
|
||||
assert_eq!(U256::from_str("271000000000000").unwrap(), reward);
|
||||
|
||||
let block_number = 250000000;
|
||||
let (eras, reward) = ecip1017_eras_block_reward(eras_rounds, start_reward, block_number);
|
||||
assert_eq!(49, eras);
|
||||
assert_eq!(U256::from_str("51212FFBAF0A").unwrap(), reward);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -137,9 +137,14 @@ pub fn verify_block_family(header: &Header, parent: &Header, engine: &EthEngine,
|
||||
|
||||
fn verify_uncles(header: &Header, bytes: &[u8], bc: &BlockProvider, engine: &EthEngine) -> Result<(), Error> {
|
||||
let num_uncles = UntrustedRlp::new(bytes).at(2)?.item_count()?;
|
||||
let max_uncles = engine.maximum_uncle_count(header.number());
|
||||
if num_uncles != 0 {
|
||||
if num_uncles > engine.maximum_uncle_count() {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds { min: None, max: Some(engine.maximum_uncle_count()), found: num_uncles })));
|
||||
if num_uncles > max_uncles {
|
||||
return Err(From::from(BlockError::TooManyUncles(OutOfBounds {
|
||||
min: None,
|
||||
max: Some(max_uncles),
|
||||
found: num_uncles,
|
||||
})));
|
||||
}
|
||||
|
||||
let mut excluded = HashSet::new();
|
||||
@ -653,7 +658,7 @@ mod tests {
|
||||
let mut bad_uncles = good_uncles.clone();
|
||||
bad_uncles.push(good_uncle1.clone());
|
||||
check_fail(family_test(&create_test_block_with_data(&header, &good_transactions, &bad_uncles), engine, &bc),
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count()), min: None, found: bad_uncles.len() }));
|
||||
TooManyUncles(OutOfBounds { max: Some(engine.maximum_uncle_count(header.number())), min: None, found: bad_uncles.len() }));
|
||||
|
||||
header = good.clone();
|
||||
bad_uncles = vec![ good_uncle1.clone(), good_uncle1.clone() ];
|
||||
|
@ -25,12 +25,12 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
Static(
|
||||
"_storage_read",
|
||||
&[I32; 2],
|
||||
Some(I32),
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_storage_write",
|
||||
&[I32; 2],
|
||||
Some(I32),
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_balance",
|
||||
@ -115,7 +115,7 @@ pub const SIGNATURES: &'static [UserFunctionDescriptor] = &[
|
||||
Static(
|
||||
"_blockhash",
|
||||
&[I64, I32],
|
||||
Some(I32),
|
||||
None,
|
||||
),
|
||||
Static(
|
||||
"_coinbase",
|
||||
|
@ -31,6 +31,7 @@ mod result;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
mod env;
|
||||
mod panic_payload;
|
||||
|
||||
const DEFAULT_STACK_SPACE: u32 = 5 * 1024 * 1024;
|
||||
|
||||
|
168
ethcore/wasm/src/panic_payload.rs
Normal file
168
ethcore/wasm/src/panic_payload.rs
Normal file
@ -0,0 +1,168 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
use byteorder::{LittleEndian, ReadBytesExt};
|
||||
use std::io::{self, Read};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub struct PanicPayload {
|
||||
pub msg: Option<String>,
|
||||
pub file: Option<String>,
|
||||
pub line: Option<u32>,
|
||||
pub col: Option<u32>,
|
||||
}
|
||||
|
||||
fn read_string(rdr: &mut io::Cursor<&[u8]>) -> io::Result<Option<String>> {
|
||||
let string_len = rdr.read_u32::<LittleEndian>()?;
|
||||
let string = if string_len == 0 {
|
||||
None
|
||||
} else {
|
||||
let mut content = vec![0; string_len as usize];
|
||||
rdr.read_exact(&mut content)?;
|
||||
Some(String::from_utf8_lossy(&content).into_owned())
|
||||
};
|
||||
Ok(string)
|
||||
}
|
||||
|
||||
pub fn decode(raw: &[u8]) -> PanicPayload {
|
||||
let mut rdr = io::Cursor::new(raw);
|
||||
let msg = read_string(&mut rdr).ok().and_then(|x| x);
|
||||
let file = read_string(&mut rdr).ok().and_then(|x| x);
|
||||
let line = rdr.read_u32::<LittleEndian>().ok();
|
||||
let col = rdr.read_u32::<LittleEndian>().ok();
|
||||
PanicPayload {
|
||||
msg: msg,
|
||||
file: file,
|
||||
line: line,
|
||||
col: col,
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use byteorder::WriteBytesExt;
|
||||
|
||||
fn write_u32(payload: &mut Vec<u8>, val: u32) {
|
||||
payload.write_u32::<LittleEndian>(val).unwrap();
|
||||
}
|
||||
|
||||
fn write_bytes(payload: &mut Vec<u8>, bytes: &[u8]) {
|
||||
write_u32(payload, bytes.len() as u32);
|
||||
payload.extend(bytes);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn only_msg() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: None,
|
||||
line: None,
|
||||
col: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_utf8() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"\xF0\x90\x80msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("<EFBFBD>msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn trailing_data() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"file");
|
||||
write_u32(&mut raw, 1);
|
||||
write_u32(&mut raw, 2);
|
||||
write_u32(&mut raw, 0xdeadbeef);
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: Some("file".to_string()),
|
||||
line: Some(1),
|
||||
col: Some(2),
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_str_is_none() {
|
||||
let mut raw = Vec::new();
|
||||
write_bytes(&mut raw, b"msg");
|
||||
write_bytes(&mut raw, b"");
|
||||
|
||||
let payload = decode(&raw);
|
||||
|
||||
assert_eq!(
|
||||
payload,
|
||||
PanicPayload {
|
||||
msg: Some("msg".to_string()),
|
||||
file: None,
|
||||
line: None,
|
||||
col: None,
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
@ -21,6 +21,7 @@ use std::sync::Arc;
|
||||
use byteorder::{LittleEndian, ByteOrder};
|
||||
|
||||
use vm;
|
||||
use panic_payload;
|
||||
use parity_wasm::interpreter;
|
||||
use wasm_utils::rules;
|
||||
use bigint::prelude::U256;
|
||||
@ -167,7 +168,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
|
||||
self.ext.set_storage(key, val).map_err(|_| UserTrap::StorageUpdateError)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Read from the storage to wasm memory
|
||||
@ -183,7 +184,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
|
||||
self.memory.set(val_ptr as u32, &*val)?;
|
||||
|
||||
Ok(Some(0.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Fetches balance for address
|
||||
@ -626,12 +627,26 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
fn user_panic(&mut self, context: InterpreterCallerContext)
|
||||
-> Result<Option<interpreter::RuntimeValue>, InterpreterError>
|
||||
{
|
||||
let msg_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let msg_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
let msg = String::from_utf8(self.memory.get(msg_ptr, msg_len as usize)?)
|
||||
.map_err(|_| UserTrap::BadUtf8)?;
|
||||
let payload_len = context.value_stack.pop_as::<i32>()? as u32;
|
||||
let payload_ptr = context.value_stack.pop_as::<i32>()? as u32;
|
||||
|
||||
let raw_payload = self.memory.get(payload_ptr, payload_len as usize)?;
|
||||
let payload = panic_payload::decode(&raw_payload);
|
||||
let msg = format!(
|
||||
"{msg}, {file}:{line}:{col}",
|
||||
msg = payload
|
||||
.msg
|
||||
.as_ref()
|
||||
.map(String::as_ref)
|
||||
.unwrap_or("<msg was stripped>"),
|
||||
file = payload
|
||||
.file
|
||||
.as_ref()
|
||||
.map(String::as_ref)
|
||||
.unwrap_or("<unknown>"),
|
||||
line = payload.line.unwrap_or(0),
|
||||
col = payload.col.unwrap_or(0)
|
||||
);
|
||||
trace!(target: "wasm", "Contract custom panic message: {}", msg);
|
||||
|
||||
Err(UserTrap::Panic(msg).into())
|
||||
@ -650,7 +665,7 @@ impl<'a, 'b> Runtime<'a, 'b> {
|
||||
|
||||
self.memory.set(return_ptr, &*hash)?;
|
||||
|
||||
Ok(Some(0i32.into()))
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
fn return_address_ptr(&mut self, ptr: u32, val: Address) -> Result<(), InterpreterError>
|
||||
|
@ -112,7 +112,7 @@ fn logger() {
|
||||
U256::from(1_000_000_000),
|
||||
"Logger sets 0x04 key to the trasferred value"
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(19_143));
|
||||
assert_eq!(gas_left, U256::from(19_147));
|
||||
}
|
||||
|
||||
// This test checks if the contract can allocate memory and pass pointer to the result stream properly.
|
||||
@ -180,7 +180,7 @@ fn dispersion() {
|
||||
result,
|
||||
vec![0u8, 0, 125, 11, 197, 7, 255, 8, 19, 0]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_469));
|
||||
assert_eq!(gas_left, U256::from(96_393));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -208,7 +208,7 @@ fn suicide_not() {
|
||||
result,
|
||||
vec![0u8]
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(99_724));
|
||||
assert_eq!(gas_left, U256::from(96_725));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -240,7 +240,7 @@ fn suicide() {
|
||||
};
|
||||
|
||||
assert!(ext.suicides.contains(&refund));
|
||||
assert_eq!(gas_left, U256::from(99_663));
|
||||
assert_eq!(gas_left, U256::from(96_687));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -270,7 +270,7 @@ fn create() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Create,
|
||||
gas: U256::from(65_903),
|
||||
gas: U256::from(65_899),
|
||||
sender_address: None,
|
||||
receive_address: None,
|
||||
value: Some(1_000_000_000.into()),
|
||||
@ -278,7 +278,7 @@ fn create() {
|
||||
code_address: None,
|
||||
}
|
||||
));
|
||||
assert_eq!(gas_left, U256::from(65_896));
|
||||
assert_eq!(gas_left, U256::from(65_892));
|
||||
}
|
||||
|
||||
|
||||
@ -312,7 +312,7 @@ fn call_code() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(98_709),
|
||||
gas: U256::from(98_713),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -324,7 +324,7 @@ fn call_code() {
|
||||
// siphash result
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 4198595614);
|
||||
assert_eq!(gas_left, U256::from(93_851));
|
||||
assert_eq!(gas_left, U256::from(93_855));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -357,7 +357,7 @@ fn call_static() {
|
||||
assert!(ext.calls.contains(
|
||||
&FakeCall {
|
||||
call_type: FakeCallType::Call,
|
||||
gas: U256::from(98_709),
|
||||
gas: U256::from(98_713),
|
||||
sender_address: Some(sender),
|
||||
receive_address: Some(receiver),
|
||||
value: None,
|
||||
@ -370,7 +370,7 @@ fn call_static() {
|
||||
let res = LittleEndian::read_u32(&result[..]);
|
||||
assert_eq!(res, 317632590);
|
||||
|
||||
assert_eq!(gas_left, U256::from(93_851));
|
||||
assert_eq!(gas_left, U256::from(93_855));
|
||||
}
|
||||
|
||||
// Realloc test
|
||||
@ -393,7 +393,7 @@ fn realloc() {
|
||||
}
|
||||
};
|
||||
assert_eq!(result, vec![0u8; 2]);
|
||||
assert_eq!(gas_left, U256::from(99_787));
|
||||
assert_eq!(gas_left, U256::from(96_723));
|
||||
}
|
||||
|
||||
// Tests that contract's ability to read from a storage
|
||||
@ -419,7 +419,7 @@ fn storage_read() {
|
||||
};
|
||||
|
||||
assert_eq!(Address::from(&result[12..32]), address);
|
||||
assert_eq!(gas_left, U256::from(99_702));
|
||||
assert_eq!(gas_left, U256::from(99_767));
|
||||
}
|
||||
|
||||
// Tests keccak calculation
|
||||
@ -445,7 +445,7 @@ fn keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(84_520));
|
||||
assert_eq!(gas_left, U256::from(81_446));
|
||||
}
|
||||
|
||||
// memcpy test.
|
||||
@ -477,7 +477,7 @@ fn memcpy() {
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
assert_eq!(gas_left, U256::from(72_216));
|
||||
}
|
||||
|
||||
// memmove test.
|
||||
@ -509,7 +509,7 @@ fn memmove() {
|
||||
};
|
||||
|
||||
assert_eq!(result, test_payload);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
assert_eq!(gas_left, U256::from(72_216));
|
||||
}
|
||||
|
||||
// memset test
|
||||
@ -534,7 +534,7 @@ fn memset() {
|
||||
};
|
||||
|
||||
assert_eq!(result, vec![228u8; 8192]);
|
||||
assert_eq!(gas_left, U256::from(75_324));
|
||||
assert_eq!(gas_left, U256::from(72_196));
|
||||
}
|
||||
|
||||
macro_rules! reqrep_test {
|
||||
@ -591,7 +591,7 @@ fn math_add() {
|
||||
U256::from_dec_str("1888888888888888888888888888887").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(98_576));
|
||||
assert_eq!(gas_left, U256::from(95_524));
|
||||
}
|
||||
|
||||
// multiplication
|
||||
@ -613,7 +613,7 @@ fn math_mul() {
|
||||
U256::from_dec_str("888888888888888888888888888887111111111111111111111111111112").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(97_726));
|
||||
assert_eq!(gas_left, U256::from(94_674));
|
||||
}
|
||||
|
||||
// subtraction
|
||||
@ -635,7 +635,7 @@ fn math_sub() {
|
||||
U256::from_dec_str("111111111111111111111111111111").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(98_568));
|
||||
assert_eq!(gas_left, U256::from(95_516));
|
||||
}
|
||||
|
||||
// subtraction with overflow
|
||||
@ -677,7 +677,7 @@ fn math_div() {
|
||||
U256::from_dec_str("1125000").unwrap(),
|
||||
(&result[..]).into()
|
||||
);
|
||||
assert_eq!(gas_left, U256::from(91_564));
|
||||
assert_eq!(gas_left, U256::from(88_514));
|
||||
}
|
||||
|
||||
// This test checks the ability of wasm contract to invoke
|
||||
@ -765,7 +765,7 @@ fn externs() {
|
||||
"Gas limit requested and returned does not match"
|
||||
);
|
||||
|
||||
assert_eq!(gas_left, U256::from(97_740));
|
||||
assert_eq!(gas_left, U256::from(94_858));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -791,7 +791,7 @@ fn embedded_keccak() {
|
||||
};
|
||||
|
||||
assert_eq!(H256::from_slice(&result), H256::from("68371d7e884c168ae2022c82bd837d51837718a7f7dfb7aa3f753074a35e1d87"));
|
||||
assert_eq!(gas_left, U256::from(84_520));
|
||||
assert_eq!(gas_left, U256::from(81_446));
|
||||
}
|
||||
|
||||
/// This test checks the correctness of log extern
|
||||
@ -826,5 +826,5 @@ fn events() {
|
||||
assert_eq!(&log_entry.data, b"gnihtemos");
|
||||
|
||||
assert_eq!(&result, b"gnihtemos");
|
||||
assert_eq!(gas_left, U256::from(82_721));
|
||||
assert_eq!(gas_left, U256::from(79_637));
|
||||
}
|
||||
|
@ -43,6 +43,12 @@ pub struct AuthorityRoundParams {
|
||||
/// Reward per block in wei.
|
||||
#[serde(rename="blockReward")]
|
||||
pub block_reward: Option<Uint>,
|
||||
/// Block at which maximum uncle count should be considered.
|
||||
#[serde(rename="maximumUncleCountTransition")]
|
||||
pub maximum_uncle_count_transition: Option<Uint>,
|
||||
/// Maximum number of accepted uncles.
|
||||
#[serde(rename="maximumUncleCount")]
|
||||
pub maximum_uncle_count: Option<Uint>,
|
||||
}
|
||||
|
||||
/// Authority engine deserialization.
|
||||
@ -71,7 +77,9 @@ mod tests {
|
||||
},
|
||||
"startStep" : 24,
|
||||
"validateStepTransition": 150,
|
||||
"blockReward": 5000000
|
||||
"blockReward": 5000000,
|
||||
"maximumUncleCountTransition": 10000000,
|
||||
"maximumUncleCount": 5
|
||||
}
|
||||
}"#;
|
||||
|
||||
@ -80,6 +88,8 @@ mod tests {
|
||||
assert_eq!(deserialized.params.validators, ValidatorSet::List(vec![Address(H160::from("0xc6d9d2cd449a754c494264e1809c50e34d64562b"))]));
|
||||
assert_eq!(deserialized.params.start_step, Some(Uint(U256::from(24))));
|
||||
assert_eq!(deserialized.params.immediate_transitions, None);
|
||||
assert_eq!(deserialized.params.maximum_uncle_count_transition, Some(Uint(10_000_000.into())));
|
||||
assert_eq!(deserialized.params.maximum_uncle_count, Some(Uint(5.into())));
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -195,9 +195,7 @@ mod server {
|
||||
|
||||
pub struct Middleware;
|
||||
impl RequestMiddleware for Middleware {
|
||||
fn on_request(
|
||||
&self, _req: &hyper::server::Request<hyper::net::HttpStream>, _control: &hyper::Control
|
||||
) -> RequestMiddlewareAction {
|
||||
fn on_request(&self, _req: hyper::Request) -> RequestMiddlewareAction {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user