Merge remote-tracking branch 'origin/master' into beta
This commit is contained in:
commit
9885bdcf0a
6
Cargo.lock
generated
6
Cargo.lock
generated
@ -284,7 +284,7 @@ dependencies = [
|
|||||||
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mime_guess 1.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
|
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
|
||||||
"parity-dapps-builtins 0.5.1 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)",
|
"parity-dapps-builtins 0.5.2 (git+https://github.com/ethcore/parity-dapps-builtins-rs.git)",
|
||||||
"parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)",
|
"parity-dapps-status 0.5.0 (git+https://github.com/ethcore/parity-dapps-status-rs.git)",
|
||||||
"parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)",
|
"parity-dapps-wallet 0.6.1 (git+https://github.com/ethcore/parity-dapps-wallet-rs.git)",
|
||||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@ -909,8 +909,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parity-dapps-builtins"
|
name = "parity-dapps-builtins"
|
||||||
version = "0.5.1"
|
version = "0.5.2"
|
||||||
source = "git+https://github.com/ethcore/parity-dapps-builtins-rs.git#7408838e8ca3b57c6b0cf5da2e31e0e275959955"
|
source = "git+https://github.com/ethcore/parity-dapps-builtins-rs.git#01af2091d5d70dfe0aecbfd96308f0ae79fc61e6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
|
"parity-dapps 0.3.0 (git+https://github.com/ethcore/parity-dapps-rs.git)",
|
||||||
]
|
]
|
||||||
|
19
appveyor.yml
19
appveyor.yml
@ -1,13 +1,27 @@
|
|||||||
environment:
|
environment:
|
||||||
matrix:
|
matrix:
|
||||||
- TARGET: x86_64-pc-windows-msvc
|
- TARGET: x86_64-pc-windows-msvc
|
||||||
|
cert:
|
||||||
|
secure: ESPpYVVAMG1fbJx6kq4ct/g9SQTXac4Hs6xXr6Oh4Zrk2dwYglNjxmzErdPnvu7gs/gekzrJ6KEQHYRc+5+4dKg6rRADQ681NLVx9vOggBs=
|
||||||
|
certpass:
|
||||||
|
secure: 0BgXJqxq9Ei34/hZ7121FQ==
|
||||||
|
keyfile: C:\users\appveyor\Certificates.p12
|
||||||
|
|
||||||
|
branches:
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
- /^beta-.*$/
|
||||||
|
- /^stable-.*$/
|
||||||
|
- /^beta$/
|
||||||
|
- /^stable$/
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- git submodule update --init --recursive
|
- git submodule update --init --recursive
|
||||||
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-x86_64-pc-windows-msvc.exe"
|
- ps: Start-FileDownload "https://static.rust-lang.org/dist/rust-1.9.0-x86_64-pc-windows-msvc.exe"
|
||||||
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll
|
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/SimpleFC.dll" -FileName nsis\SimpleFC.dll
|
||||||
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe
|
- ps: Start-FileDownload "https://github.com/ethcore/win-build/raw/master/vc_redist.x64.exe" -FileName nsis\vc_redist.x64.exe
|
||||||
- rust-1.9.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
- rust-1.9.0-x86_64-pc-windows-msvc.exe /VERYSILENT /NORESTART /DIR="C:\Program Files (x86)\Rust"
|
||||||
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS
|
- SET PATH=%PATH%;C:\Program Files (x86)\Rust\bin;C:\Program Files (x86)\NSIS;C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Bin
|
||||||
- rustc -V
|
- rustc -V
|
||||||
- cargo -V
|
- cargo -V
|
||||||
|
|
||||||
@ -18,7 +32,10 @@ test_script:
|
|||||||
|
|
||||||
after_test:
|
after_test:
|
||||||
- cargo build --verbose --release
|
- cargo build --verbose --release
|
||||||
|
- ps: if($env:cert) { Start-FileDownload $env:cert -FileName $env:keyfile }
|
||||||
|
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass target\release\parity.exe }
|
||||||
- makensis.exe nsis\installer.nsi
|
- makensis.exe nsis\installer.nsi
|
||||||
|
- ps: if($env:cert) { signtool sign /f $env:keyfile /p $env:certpass nsis\installer.exe }
|
||||||
|
|
||||||
artifacts:
|
artifacts:
|
||||||
- path: nsis\installer.exe
|
- path: nsis\installer.exe
|
||||||
|
@ -23,7 +23,7 @@ ethcore-util = { path = "../util" }
|
|||||||
parity-dapps = { git = "https://github.com/ethcore/parity-dapps-rs.git", version = "0.3" }
|
parity-dapps = { git = "https://github.com/ethcore/parity-dapps-rs.git", version = "0.3" }
|
||||||
# List of apps
|
# List of apps
|
||||||
parity-dapps-status = { git = "https://github.com/ethcore/parity-dapps-status-rs.git", version = "0.5.0" }
|
parity-dapps-status = { git = "https://github.com/ethcore/parity-dapps-status-rs.git", version = "0.5.0" }
|
||||||
parity-dapps-builtins = { git = "https://github.com/ethcore/parity-dapps-builtins-rs.git", version = "0.5.0" }
|
parity-dapps-builtins = { git = "https://github.com/ethcore/parity-dapps-builtins-rs.git", version = "0.5.2" }
|
||||||
parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs.git", version = "0.6.0", optional = true }
|
parity-dapps-wallet = { git = "https://github.com/ethcore/parity-dapps-wallet-rs.git", version = "0.6.0", optional = true }
|
||||||
parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true }
|
parity-dapps-dao = { git = "https://github.com/ethcore/parity-dapps-dao-rs.git", version = "0.4.0", optional = true }
|
||||||
parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.3.0", optional = true }
|
parity-dapps-makerotc = { git = "https://github.com/ethcore/parity-dapps-makerotc-rs.git", version = "0.3.0", optional = true }
|
||||||
|
@ -108,6 +108,12 @@ impl Account {
|
|||||||
self.code_cache = code;
|
self.code_cache = code;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset this account's code to the given code.
|
||||||
|
pub fn reset_code(&mut self, code: Bytes) {
|
||||||
|
self.code_hash = None;
|
||||||
|
self.init_code(code);
|
||||||
|
}
|
||||||
|
|
||||||
/// Set (and cache) the contents of the trie's storage at `key` to `value`.
|
/// Set (and cache) the contents of the trie's storage at `key` to `value`.
|
||||||
pub fn set_storage(&mut self, key: H256, value: H256) {
|
pub fn set_storage(&mut self, key: H256, value: H256) {
|
||||||
self.storage_overlay.borrow_mut().insert(key, (Filth::Dirty, value));
|
self.storage_overlay.borrow_mut().insert(key, (Filth::Dirty, value));
|
||||||
@ -336,6 +342,21 @@ mod tests {
|
|||||||
assert_eq!(a.code_hash().hex(), "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb");
|
assert_eq!(a.code_hash().hex(), "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn reset_code() {
|
||||||
|
let mut a = Account::new_contract(69.into(), 0.into());
|
||||||
|
let mut db = MemoryDB::new();
|
||||||
|
let mut db = AccountDBMut::new(&mut db, &Address::new());
|
||||||
|
a.init_code(vec![0x55, 0x44, 0xffu8]);
|
||||||
|
assert_eq!(a.code_hash(), SHA3_EMPTY);
|
||||||
|
a.commit_code(&mut db);
|
||||||
|
assert_eq!(a.code_hash().hex(), "af231e631776a517ca23125370d542873eca1fb4d613ed9b5d5335a46ae5b7eb");
|
||||||
|
a.reset_code(vec![0x55]);
|
||||||
|
assert_eq!(a.code_hash(), SHA3_EMPTY);
|
||||||
|
a.commit_code(&mut db);
|
||||||
|
assert_eq!(a.code_hash().hex(), "37bf2238b11b68cdc8382cece82651b59d3c3988873b6e0f33d79694aa45f1be");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn rlpio() {
|
fn rlpio() {
|
||||||
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
||||||
@ -348,7 +369,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn new_account() {
|
fn new_account() {
|
||||||
|
|
||||||
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
||||||
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
||||||
assert_eq!(a.balance(), &U256::from(69u8));
|
assert_eq!(a.balance(), &U256::from(69u8));
|
||||||
@ -359,7 +379,6 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_account() {
|
fn create_account() {
|
||||||
|
|
||||||
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
let a = Account::new(U256::from(69u8), U256::from(0u8), HashMap::new(), Bytes::new());
|
||||||
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
assert_eq!(a.rlp().to_hex(), "f8448045a056e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421a0c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470");
|
||||||
}
|
}
|
||||||
|
@ -515,9 +515,6 @@ impl BlockChainClient for Client {
|
|||||||
ret
|
ret
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vm_factory(&self) -> &EvmFactory {
|
|
||||||
&self.vm_factory
|
|
||||||
}
|
|
||||||
|
|
||||||
fn block_header(&self, id: BlockID) -> Option<Bytes> {
|
fn block_header(&self, id: BlockID) -> Option<Bytes> {
|
||||||
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
Self::block_hash(&self.chain, id).and_then(|hash| self.chain.block(&hash).map(|bytes| BlockView::new(&bytes).rlp().at(0).as_raw().to_vec()))
|
||||||
@ -829,6 +826,10 @@ impl MiningBlockChainClient for Client {
|
|||||||
|
|
||||||
open_block
|
open_block
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vm_factory(&self) -> &EvmFactory {
|
||||||
|
&self.vm_factory
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MayPanic for Client {
|
impl MayPanic for Client {
|
||||||
|
@ -172,9 +172,6 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
// TODO: should be able to accept blockchain location for call.
|
// TODO: should be able to accept blockchain location for call.
|
||||||
fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, ExecutionError>;
|
fn call(&self, t: &SignedTransaction, analytics: CallAnalytics) -> Result<Executed, ExecutionError>;
|
||||||
|
|
||||||
/// Returns EvmFactory.
|
|
||||||
fn vm_factory(&self) -> &EvmFactory;
|
|
||||||
|
|
||||||
/// Returns traces matching given filter.
|
/// Returns traces matching given filter.
|
||||||
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
|
fn filter_traces(&self, filter: TraceFilter) -> Option<Vec<LocalizedTrace>>;
|
||||||
|
|
||||||
@ -253,4 +250,7 @@ pub trait MiningBlockChainClient : BlockChainClient {
|
|||||||
/// Returns OpenBlock prepared for closing.
|
/// Returns OpenBlock prepared for closing.
|
||||||
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes)
|
fn prepare_open_block(&self, author: Address, gas_range_target: (U256, U256), extra_data: Bytes)
|
||||||
-> OpenBlock;
|
-> OpenBlock;
|
||||||
|
|
||||||
|
/// Returns EvmFactory.
|
||||||
|
fn vm_factory(&self) -> &EvmFactory;
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,10 @@ impl MiningBlockChainClient for TestBlockChainClient {
|
|||||||
fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock {
|
fn prepare_open_block(&self, _author: Address, _gas_range_target: (U256, U256), _extra_data: Bytes) -> OpenBlock {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn vm_factory(&self) -> &EvmFactory {
|
||||||
|
unimplemented!();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BlockChainClient for TestBlockChainClient {
|
impl BlockChainClient for TestBlockChainClient {
|
||||||
@ -463,10 +467,6 @@ impl BlockChainClient for TestBlockChainClient {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn vm_factory(&self) -> &EvmFactory {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
|
fn filter_traces(&self, _filter: TraceFilter) -> Option<Vec<LocalizedTrace>> {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::sync::atomic::AtomicBool;
|
use std::sync::atomic::AtomicBool;
|
||||||
|
use std::time::{Instant, Duration};
|
||||||
|
|
||||||
use util::*;
|
use util::*;
|
||||||
use account_provider::AccountProvider;
|
use account_provider::AccountProvider;
|
||||||
@ -50,12 +51,16 @@ pub struct MinerOptions {
|
|||||||
pub reseal_on_external_tx: bool,
|
pub reseal_on_external_tx: bool,
|
||||||
/// Reseal on receipt of new local transactions.
|
/// Reseal on receipt of new local transactions.
|
||||||
pub reseal_on_own_tx: bool,
|
pub reseal_on_own_tx: bool,
|
||||||
|
/// Minimum period between transaction-inspired reseals.
|
||||||
|
pub reseal_min_period: Duration,
|
||||||
/// Maximum amount of gas to bother considering for block insertion.
|
/// Maximum amount of gas to bother considering for block insertion.
|
||||||
pub tx_gas_limit: U256,
|
pub tx_gas_limit: U256,
|
||||||
/// Maximum size of the transaction queue.
|
/// Maximum size of the transaction queue.
|
||||||
pub tx_queue_size: usize,
|
pub tx_queue_size: usize,
|
||||||
/// Whether we should fallback to providing all the queue's transactions or just pending.
|
/// Whether we should fallback to providing all the queue's transactions or just pending.
|
||||||
pub pending_set: PendingSet,
|
pub pending_set: PendingSet,
|
||||||
|
/// How many historical work packages can we store before running out?
|
||||||
|
pub work_queue_size: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MinerOptions {
|
impl Default for MinerOptions {
|
||||||
@ -67,6 +72,8 @@ impl Default for MinerOptions {
|
|||||||
tx_gas_limit: !U256::zero(),
|
tx_gas_limit: !U256::zero(),
|
||||||
tx_queue_size: 1024,
|
tx_queue_size: 1024,
|
||||||
pending_set: PendingSet::AlwaysQueue,
|
pending_set: PendingSet::AlwaysQueue,
|
||||||
|
reseal_min_period: Duration::from_secs(0),
|
||||||
|
work_queue_size: 20,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,6 +87,7 @@ pub struct Miner {
|
|||||||
// for sealing...
|
// for sealing...
|
||||||
options: MinerOptions,
|
options: MinerOptions,
|
||||||
sealing_enabled: AtomicBool,
|
sealing_enabled: AtomicBool,
|
||||||
|
next_allowed_reseal: Mutex<Instant>,
|
||||||
sealing_block_last_request: Mutex<u64>,
|
sealing_block_last_request: Mutex<u64>,
|
||||||
gas_range_target: RwLock<(U256, U256)>,
|
gas_range_target: RwLock<(U256, U256)>,
|
||||||
author: RwLock<Address>,
|
author: RwLock<Address>,
|
||||||
@ -96,8 +104,9 @@ impl Miner {
|
|||||||
transaction_queue: Mutex::new(TransactionQueue::new()),
|
transaction_queue: Mutex::new(TransactionQueue::new()),
|
||||||
options: Default::default(),
|
options: Default::default(),
|
||||||
sealing_enabled: AtomicBool::new(false),
|
sealing_enabled: AtomicBool::new(false),
|
||||||
|
next_allowed_reseal: Mutex::new(Instant::now()),
|
||||||
sealing_block_last_request: Mutex::new(0),
|
sealing_block_last_request: Mutex::new(0),
|
||||||
sealing_work: Mutex::new(UsingQueue::new(5)),
|
sealing_work: Mutex::new(UsingQueue::new(20)),
|
||||||
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
|
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
|
||||||
author: RwLock::new(Address::default()),
|
author: RwLock::new(Address::default()),
|
||||||
extra_data: RwLock::new(Vec::new()),
|
extra_data: RwLock::new(Vec::new()),
|
||||||
@ -111,13 +120,14 @@ impl Miner {
|
|||||||
Arc::new(Miner {
|
Arc::new(Miner {
|
||||||
transaction_queue: Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)),
|
transaction_queue: Mutex::new(TransactionQueue::with_limits(options.tx_queue_size, options.tx_gas_limit)),
|
||||||
sealing_enabled: AtomicBool::new(options.force_sealing),
|
sealing_enabled: AtomicBool::new(options.force_sealing),
|
||||||
options: options,
|
next_allowed_reseal: Mutex::new(Instant::now()),
|
||||||
sealing_block_last_request: Mutex::new(0),
|
sealing_block_last_request: Mutex::new(0),
|
||||||
sealing_work: Mutex::new(UsingQueue::new(5)),
|
sealing_work: Mutex::new(UsingQueue::new(options.work_queue_size)),
|
||||||
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
|
gas_range_target: RwLock::new((U256::zero(), U256::zero())),
|
||||||
author: RwLock::new(Address::default()),
|
author: RwLock::new(Address::default()),
|
||||||
extra_data: RwLock::new(Vec::new()),
|
extra_data: RwLock::new(Vec::new()),
|
||||||
accounts: accounts,
|
accounts: accounts,
|
||||||
|
options: options,
|
||||||
spec: spec,
|
spec: spec,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -261,6 +271,9 @@ impl Miner {
|
|||||||
// Return if
|
// Return if
|
||||||
!have_work
|
!have_work
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Are we allowed to do a non-mandatory reseal?
|
||||||
|
fn tx_reseal_allowed(&self) -> bool { Instant::now() > *self.next_allowed_reseal.lock().unwrap() }
|
||||||
}
|
}
|
||||||
|
|
||||||
const SEALING_TIMEOUT_IN_BLOCKS : u64 = 5;
|
const SEALING_TIMEOUT_IN_BLOCKS : u64 = 5;
|
||||||
@ -431,7 +444,7 @@ impl MinerService for Miner {
|
|||||||
.map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External))
|
.map(|tx| transaction_queue.add(tx, &fetch_account, TransactionOrigin::External))
|
||||||
.collect()
|
.collect()
|
||||||
};
|
};
|
||||||
if !results.is_empty() && self.options.reseal_on_external_tx {
|
if !results.is_empty() && self.options.reseal_on_external_tx && self.tx_reseal_allowed() {
|
||||||
self.update_sealing(chain);
|
self.update_sealing(chain);
|
||||||
}
|
}
|
||||||
results
|
results
|
||||||
@ -466,7 +479,7 @@ impl MinerService for Miner {
|
|||||||
import
|
import
|
||||||
};
|
};
|
||||||
|
|
||||||
if imported.is_ok() && self.options.reseal_on_own_tx {
|
if imported.is_ok() && self.options.reseal_on_own_tx && self.tx_reseal_allowed() {
|
||||||
// Make sure to do it after transaction is imported and lock is droped.
|
// Make sure to do it after transaction is imported and lock is droped.
|
||||||
// We need to create pending block and enable sealing
|
// We need to create pending block and enable sealing
|
||||||
let prepared = self.enable_and_prepare_sealing(chain);
|
let prepared = self.enable_and_prepare_sealing(chain);
|
||||||
@ -559,6 +572,7 @@ impl MinerService for Miner {
|
|||||||
self.sealing_enabled.store(false, atomic::Ordering::Relaxed);
|
self.sealing_enabled.store(false, atomic::Ordering::Relaxed);
|
||||||
self.sealing_work.lock().unwrap().reset();
|
self.sealing_work.lock().unwrap().reset();
|
||||||
} else {
|
} else {
|
||||||
|
*self.next_allowed_reseal.lock().unwrap() = Instant::now() + self.options.reseal_min_period;
|
||||||
self.prepare_sealing(chain);
|
self.prepare_sealing(chain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +441,7 @@ impl TransactionQueue {
|
|||||||
|
|
||||||
trace!(target: "miner", "Importing: {:?}", tx.hash());
|
trace!(target: "miner", "Importing: {:?}", tx.hash());
|
||||||
|
|
||||||
if tx.gas_price < self.minimal_gas_price {
|
if tx.gas_price < self.minimal_gas_price && origin != TransactionOrigin::Local {
|
||||||
trace!(target: "miner",
|
trace!(target: "miner",
|
||||||
"Dropping transaction below minimal gas price threshold: {:?} (gp: {} < {})",
|
"Dropping transaction below minimal gas price threshold: {:?} (gp: {} < {})",
|
||||||
tx.hash(),
|
tx.hash(),
|
||||||
@ -1055,7 +1055,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_not_import_transaction_below_min_gas_price_threshold() {
|
fn should_not_import_transaction_below_min_gas_price_threshold_if_external() {
|
||||||
// given
|
// given
|
||||||
let mut txq = TransactionQueue::new();
|
let mut txq = TransactionQueue::new();
|
||||||
let tx = new_tx();
|
let tx = new_tx();
|
||||||
@ -1074,6 +1074,23 @@ mod test {
|
|||||||
assert_eq!(stats.future, 0);
|
assert_eq!(stats.future, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_import_transaction_below_min_gas_price_threshold_if_local() {
|
||||||
|
// given
|
||||||
|
let mut txq = TransactionQueue::new();
|
||||||
|
let tx = new_tx();
|
||||||
|
txq.set_minimal_gas_price(tx.gas_price + U256::one());
|
||||||
|
|
||||||
|
// when
|
||||||
|
let res = txq.add(tx, &default_nonce, TransactionOrigin::Local);
|
||||||
|
|
||||||
|
// then
|
||||||
|
assert_eq!(res.unwrap(), TransactionImportResult::Current);
|
||||||
|
let stats = txq.status();
|
||||||
|
assert_eq!(stats.pending, 1);
|
||||||
|
assert_eq!(stats.future, 0);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn should_reject_incorectly_signed_transaction() {
|
fn should_reject_incorectly_signed_transaction() {
|
||||||
// given
|
// given
|
||||||
|
@ -208,12 +208,17 @@ impl State {
|
|||||||
self.require(a, false).set_storage(key, value)
|
self.require(a, false).set_storage(key, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Initialise the code of account `a` so that it is `value` for `key`.
|
/// Initialise the code of account `a` so that it is `code`.
|
||||||
/// NOTE: Account should have been created with `new_contract`.
|
/// NOTE: Account should have been created with `new_contract`.
|
||||||
pub fn init_code(&mut self, a: &Address, code: Bytes) {
|
pub fn init_code(&mut self, a: &Address, code: Bytes) {
|
||||||
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{}).init_code(code);
|
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{}).init_code(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Reset the code of account `a` so that it is `code`.
|
||||||
|
pub fn reset_code(&mut self, a: &Address, code: Bytes) {
|
||||||
|
self.require_or_from(a, true, || Account::new_contract(0.into(), self.account_start_nonce), |_|{}).reset_code(code);
|
||||||
|
}
|
||||||
|
|
||||||
/// Execute a given transaction.
|
/// Execute a given transaction.
|
||||||
/// This will change the state accordingly.
|
/// This will change the state accordingly.
|
||||||
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, vm_factory: &EvmFactory, t: &SignedTransaction, tracing: bool) -> ApplyResult {
|
pub fn apply(&mut self, env_info: &EnvInfo, engine: &Engine, vm_factory: &EvmFactory, t: &SignedTransaction, tracing: bool) -> ApplyResult {
|
||||||
|
@ -42,14 +42,12 @@ Protocol Options:
|
|||||||
--keys-path PATH Specify the path for JSON key files to be found
|
--keys-path PATH Specify the path for JSON key files to be found
|
||||||
[default: $HOME/.parity/keys].
|
[default: $HOME/.parity/keys].
|
||||||
--identity NAME Specify your node's name.
|
--identity NAME Specify your node's name.
|
||||||
|
--fork POLICY Specifies the client's fork policy. POLICY must be
|
||||||
DAO-Rescue Soft-fork Options:
|
one of:
|
||||||
--help-rescue-dao Does nothing - on by default.
|
dogmatic - sticks rigidly to the standard chain.
|
||||||
--dont-help-rescue-dao Votes against the DAO-rescue soft-fork, but supports
|
dao-soft - votes for the DAO-rescue soft-fork.
|
||||||
it if it is triggered anyway.
|
normal - goes with whatever fork is decided but
|
||||||
Equivalent to --gas-floor-target=3141592.
|
votes for none. [default: normal].
|
||||||
--dogmatic Ignores all DAO-rescue soft-fork behaviour. Even if
|
|
||||||
it means losing mining rewards.
|
|
||||||
|
|
||||||
Account Options:
|
Account Options:
|
||||||
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
--unlock ACCOUNTS Unlock ACCOUNTS for the duration of the execution.
|
||||||
@ -139,6 +137,13 @@ Sealing/Mining Options:
|
|||||||
own - reseal only on a new local transaction;
|
own - reseal only on a new local transaction;
|
||||||
ext - reseal only on a new external transaction;
|
ext - reseal only on a new external transaction;
|
||||||
all - reseal on all new transactions [default: all].
|
all - reseal on all new transactions [default: all].
|
||||||
|
--reseal-min-period MS Specify the minimum time between reseals from
|
||||||
|
incoming transactions. MS is time measured in
|
||||||
|
milliseconds [default: 2000].
|
||||||
|
--work-queue-size ITEMS Specify the number of historical work packages
|
||||||
|
which are kept cached lest a solution is found for
|
||||||
|
them later. High values take more memory but result
|
||||||
|
in fewer unusable solutions [default: 20].
|
||||||
--tx-gas-limit GAS Apply a limit of GAS as the maximum amount of gas
|
--tx-gas-limit GAS Apply a limit of GAS as the maximum amount of gas
|
||||||
a single transaction may have for it to be mined.
|
a single transaction may have for it to be mined.
|
||||||
--relay-set SET Set of transactions to relay. SET may be:
|
--relay-set SET Set of transactions to relay. SET may be:
|
||||||
@ -157,9 +162,9 @@ Sealing/Mining Options:
|
|||||||
web service in turn and fallback on the last known
|
web service in turn and fallback on the last known
|
||||||
good value [default: auto].
|
good value [default: auto].
|
||||||
--gas-floor-target GAS Amount of gas per block to target when sealing a new
|
--gas-floor-target GAS Amount of gas per block to target when sealing a new
|
||||||
block [default: 3141592].
|
block [default: 4700000].
|
||||||
--gas-cap GAS A cap on how large we will raise the gas limit per
|
--gas-cap GAS A cap on how large we will raise the gas limit per
|
||||||
block due to transaction volume [default: 3141592].
|
block due to transaction volume [default: 6283184].
|
||||||
--extra-data STRING Specify a custom extra-data for authored blocks, no
|
--extra-data STRING Specify a custom extra-data for authored blocks, no
|
||||||
more than 32 characters.
|
more than 32 characters.
|
||||||
--tx-queue-size LIMIT Maximum amount of transactions in the queue (waiting
|
--tx-queue-size LIMIT Maximum amount of transactions in the queue (waiting
|
||||||
@ -262,8 +267,7 @@ pub struct Args {
|
|||||||
pub flag_chain: String,
|
pub flag_chain: String,
|
||||||
pub flag_db_path: String,
|
pub flag_db_path: String,
|
||||||
pub flag_identity: String,
|
pub flag_identity: String,
|
||||||
pub flag_dont_help_rescue_dao: bool,
|
pub flag_fork: String,
|
||||||
pub flag_dogmatic: bool,
|
|
||||||
pub flag_unlock: Option<String>,
|
pub flag_unlock: Option<String>,
|
||||||
pub flag_password: Vec<String>,
|
pub flag_password: Vec<String>,
|
||||||
pub flag_cache: Option<usize>,
|
pub flag_cache: Option<usize>,
|
||||||
@ -305,6 +309,8 @@ pub struct Args {
|
|||||||
pub flag_no_token: bool,
|
pub flag_no_token: bool,
|
||||||
pub flag_force_sealing: bool,
|
pub flag_force_sealing: bool,
|
||||||
pub flag_reseal_on_txs: String,
|
pub flag_reseal_on_txs: String,
|
||||||
|
pub flag_reseal_min_period: u64,
|
||||||
|
pub flag_work_queue_size: usize,
|
||||||
pub flag_tx_gas_limit: Option<String>,
|
pub flag_tx_gas_limit: Option<String>,
|
||||||
pub flag_relay_set: String,
|
pub flag_relay_set: String,
|
||||||
pub flag_author: Option<String>,
|
pub flag_author: Option<String>,
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
|
use std::time::Duration;
|
||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::net::{SocketAddr, IpAddr};
|
use std::net::{SocketAddr, IpAddr};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
@ -45,6 +46,13 @@ pub struct Directories {
|
|||||||
pub signer: String,
|
pub signer: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Eq, PartialEq, Debug)]
|
||||||
|
pub enum Policy {
|
||||||
|
DaoSoft,
|
||||||
|
Normal,
|
||||||
|
Dogmatic,
|
||||||
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
pub fn parse() -> Self {
|
pub fn parse() -> Self {
|
||||||
Configuration {
|
Configuration {
|
||||||
@ -96,6 +104,8 @@ impl Configuration {
|
|||||||
"lenient" => PendingSet::SealingOrElseQueue,
|
"lenient" => PendingSet::SealingOrElseQueue,
|
||||||
x => die!("{}: Invalid value for --relay-set option. Use --help for more information.", x)
|
x => die!("{}: Invalid value for --relay-set option. Use --help for more information.", x)
|
||||||
},
|
},
|
||||||
|
reseal_min_period: Duration::from_millis(self.args.flag_reseal_min_period),
|
||||||
|
work_queue_size: self.args.flag_work_queue_size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -107,9 +117,18 @@ impl Configuration {
|
|||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn policy(&self) -> Policy {
|
||||||
|
match self.args.flag_fork.as_str() {
|
||||||
|
"dao-soft" => Policy::DaoSoft,
|
||||||
|
"normal" => Policy::Normal,
|
||||||
|
"dogmatic" => Policy::Dogmatic,
|
||||||
|
x => die!("{}: Invalid value given for --policy option. Use --help for more info.", x)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn gas_floor_target(&self) -> U256 {
|
pub fn gas_floor_target(&self) -> U256 {
|
||||||
if self.args.flag_dont_help_rescue_dao || self.args.flag_dogmatic {
|
if self.policy() == Policy::DaoSoft {
|
||||||
4_700_000.into()
|
3_141_592.into()
|
||||||
} else {
|
} else {
|
||||||
let d = &self.args.flag_gas_floor_target;
|
let d = &self.args.flag_gas_floor_target;
|
||||||
U256::from_dec_str(d).unwrap_or_else(|_| {
|
U256::from_dec_str(d).unwrap_or_else(|_| {
|
||||||
@ -119,8 +138,8 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn gas_ceil_target(&self) -> U256 {
|
pub fn gas_ceil_target(&self) -> U256 {
|
||||||
if self.args.flag_dont_help_rescue_dao || self.args.flag_dogmatic {
|
if self.policy() == Policy::DaoSoft {
|
||||||
10_000_000.into()
|
3_141_592.into()
|
||||||
} else {
|
} else {
|
||||||
let d = &self.args.flag_gas_cap;
|
let d = &self.args.flag_gas_cap;
|
||||||
U256::from_dec_str(d).unwrap_or_else(|_| {
|
U256::from_dec_str(d).unwrap_or_else(|_| {
|
||||||
@ -172,7 +191,7 @@ impl Configuration {
|
|||||||
|
|
||||||
pub fn spec(&self) -> Spec {
|
pub fn spec(&self) -> Spec {
|
||||||
match self.chain().as_str() {
|
match self.chain().as_str() {
|
||||||
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(!self.args.flag_dogmatic),
|
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(self.policy() != Policy::Dogmatic),
|
||||||
"morden" | "testnet" => ethereum::new_morden(),
|
"morden" | "testnet" => ethereum::new_morden(),
|
||||||
"olympic" => ethereum::new_olympic(),
|
"olympic" => ethereum::new_olympic(),
|
||||||
f => Spec::load(contents(f).unwrap_or_else(|_| {
|
f => Spec::load(contents(f).unwrap_or_else(|_| {
|
||||||
|
@ -165,7 +165,7 @@ fn transaction_error(error: EthcoreError) -> Error {
|
|||||||
"There is too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()
|
"There is too many transactions in the queue. Your transaction was dropped due to limit. Try increasing the fee.".into()
|
||||||
},
|
},
|
||||||
InsufficientGasPrice { minimal, got } => {
|
InsufficientGasPrice { minimal, got } => {
|
||||||
format!("Transaction fee is to low. It does not satisfy your node's minimal fee (minimal: {}, got: {}). Try increasing the fee.", minimal, got)
|
format!("Transaction fee is too low. It does not satisfy your node's minimal fee (minimal: {}, got: {}). Try increasing the fee.", minimal, got)
|
||||||
},
|
},
|
||||||
InsufficientBalance { balance, cost } => {
|
InsufficientBalance { balance, cost } => {
|
||||||
format!("Insufficient funds. Account you try to send transaction from does not have enough funds. Required {} and got: {}.", cost, balance)
|
format!("Insufficient funds. Account you try to send transaction from does not have enough funds. Required {} and got: {}.", cost, balance)
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
//! rpc integration tests.
|
//! rpc integration tests.
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use ethcore::client::{BlockChainClient, Client, ClientConfig};
|
use ethcore::client::{BlockChainClient, Client, ClientConfig};
|
||||||
use ethcore::ids::BlockID;
|
use ethcore::ids::BlockID;
|
||||||
@ -57,6 +58,8 @@ fn miner_service(spec: Spec, accounts: Arc<AccountProvider>) -> Arc<Miner> {
|
|||||||
tx_queue_size: 1024,
|
tx_queue_size: 1024,
|
||||||
tx_gas_limit: !U256::zero(),
|
tx_gas_limit: !U256::zero(),
|
||||||
pending_set: PendingSet::SealingOrElseQueue,
|
pending_set: PendingSet::SealingOrElseQueue,
|
||||||
|
reseal_min_period: Duration::from_secs(0),
|
||||||
|
work_queue_size: 50,
|
||||||
},
|
},
|
||||||
spec,
|
spec,
|
||||||
Some(accounts)
|
Some(accounts)
|
||||||
|
Loading…
Reference in New Issue
Block a user