Merge pull request #1329 from ethcore/softforktrigger
Install trigger for DAO-rescue soft-fork.
This commit is contained in:
commit
7c94b1495e
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0x118c30"
|
"frontierCompatibilityModeLimit": "0x118c30",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
26729
ethcore/res/ethereum/frontier_dao_rescue.json
Normal file
26729
ethcore/res/ethereum/frontier_dao_rescue.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0x118c30"
|
"frontierCompatibilityModeLimit": "0x118c30",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
43
ethcore/res/ethereum/frontier_like_test_dao_rescue.json
Normal file
43
ethcore/res/ethereum/frontier_like_test_dao_rescue.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "Frontier (Test)",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x4563918244F40000",
|
||||||
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
|
"frontierCompatibilityModeLimit": "0x118c30",
|
||||||
|
"daoRescueSoftFork": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"accountStartNonce": "0x00",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID" : "0x1"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x400000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||||
|
"gasLimit": "0x1388"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": 0
|
"frontierCompatibilityModeLimit": 0,
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
43
ethcore/res/ethereum/homestead_test_dao_rescue.json
Normal file
43
ethcore/res/ethereum/homestead_test_dao_rescue.json
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
{
|
||||||
|
"name": "Homestead (Test)",
|
||||||
|
"engine": {
|
||||||
|
"Ethash": {
|
||||||
|
"params": {
|
||||||
|
"gasLimitBoundDivisor": "0x0400",
|
||||||
|
"minimumDifficulty": "0x020000",
|
||||||
|
"difficultyBoundDivisor": "0x0800",
|
||||||
|
"durationLimit": "0x0d",
|
||||||
|
"blockReward": "0x4563918244F40000",
|
||||||
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
|
"frontierCompatibilityModeLimit": 0,
|
||||||
|
"daoRescueSoftFork": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"params": {
|
||||||
|
"accountStartNonce": "0x00",
|
||||||
|
"maximumExtraDataSize": "0x20",
|
||||||
|
"minGasLimit": "0x1388",
|
||||||
|
"networkID" : "0x1"
|
||||||
|
},
|
||||||
|
"genesis": {
|
||||||
|
"seal": {
|
||||||
|
"ethereum": {
|
||||||
|
"nonce": "0x0000000000000042",
|
||||||
|
"mixHash": "0x0000000000000000000000000000000000000000000000000000000000000000"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"difficulty": "0x400000000",
|
||||||
|
"author": "0x0000000000000000000000000000000000000000",
|
||||||
|
"timestamp": "0x00",
|
||||||
|
"parentHash": "0x0000000000000000000000000000000000000000000000000000000000000000",
|
||||||
|
"extraData": "0x11bbe8db4e347b4e8c937c1c8370e4b5ed33adb3db69cbdb7a38e1e50b1b82fa",
|
||||||
|
"gasLimit": "0x1388"
|
||||||
|
},
|
||||||
|
"accounts": {
|
||||||
|
"0000000000000000000000000000000000000001": { "balance": "1", "builtin": { "name": "ecrecover", "pricing": { "linear": { "base": 3000, "word": 0 } } } },
|
||||||
|
"0000000000000000000000000000000000000002": { "balance": "1", "builtin": { "name": "sha256", "pricing": { "linear": { "base": 60, "word": 12 } } } },
|
||||||
|
"0000000000000000000000000000000000000003": { "balance": "1", "builtin": { "name": "ripemd160", "pricing": { "linear": { "base": 600, "word": 120 } } } },
|
||||||
|
"0000000000000000000000000000000000000004": { "balance": "1", "builtin": { "name": "identity", "pricing": { "linear": { "base": 15, "word": 3 } } } }
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar": "",
|
"registrar": "",
|
||||||
"frontierCompatibilityModeLimit": "0x789b0"
|
"frontierCompatibilityModeLimit": "0x789b0",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -9,7 +9,8 @@
|
|||||||
"durationLimit": "0x08",
|
"durationLimit": "0x08",
|
||||||
"blockReward": "0x14D1120D7B160000",
|
"blockReward": "0x14D1120D7B160000",
|
||||||
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
|
"registrar": "5e70c0bbcd5636e0f9f9316e9f8633feb64d4050",
|
||||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -203,8 +203,9 @@ mod tests {
|
|||||||
timestamp: 0,
|
timestamp: 0,
|
||||||
difficulty: 0.into(),
|
difficulty: 0.into(),
|
||||||
last_hashes: vec![],
|
last_hashes: vec![],
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
gas_used: 0.into(),
|
gas_used: 0.into(),
|
||||||
gas_limit: 0.into()
|
gas_limit: 0.into(),
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(schedule.stack_limit > 0);
|
assert!(schedule.stack_limit > 0);
|
||||||
@ -253,7 +254,7 @@ mod tests {
|
|||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, addr, 3141562.into(), vec![]).unwrap();
|
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, addr, 3141562.into(), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
|
let seal = engine.generate_seal(b.block(), Some(&tap)).unwrap();
|
||||||
assert!(b.try_seal(engine.deref(), seal).is_ok());
|
assert!(b.try_seal(engine.deref(), seal).is_ok());
|
||||||
|
@ -177,6 +177,7 @@ pub struct OpenBlock<'x> {
|
|||||||
engine: &'x Engine,
|
engine: &'x Engine,
|
||||||
vm_factory: &'x EvmFactory,
|
vm_factory: &'x EvmFactory,
|
||||||
last_hashes: LastHashes,
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
/// Just like `OpenBlock`, except that we've applied `Engine::on_close_block`, finished up the non-seal header fields,
|
||||||
@ -188,6 +189,7 @@ pub struct ClosedBlock {
|
|||||||
block: ExecutedBlock,
|
block: ExecutedBlock,
|
||||||
uncle_bytes: Bytes,
|
uncle_bytes: Bytes,
|
||||||
last_hashes: LastHashes,
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
unclosed_state: State,
|
unclosed_state: State,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -198,7 +200,6 @@ pub struct ClosedBlock {
|
|||||||
pub struct LockedBlock {
|
pub struct LockedBlock {
|
||||||
block: ExecutedBlock,
|
block: ExecutedBlock,
|
||||||
uncle_bytes: Bytes,
|
uncle_bytes: Bytes,
|
||||||
last_hashes: LastHashes,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A block that has a valid seal.
|
/// A block that has a valid seal.
|
||||||
@ -219,9 +220,10 @@ impl<'x> OpenBlock<'x> {
|
|||||||
db: Box<JournalDB>,
|
db: Box<JournalDB>,
|
||||||
parent: &Header,
|
parent: &Header,
|
||||||
last_hashes: LastHashes,
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
author: Address,
|
author: Address,
|
||||||
gas_floor_target: U256,
|
gas_floor_target: U256,
|
||||||
extra_data: Bytes
|
extra_data: Bytes,
|
||||||
) -> Result<Self, Error> {
|
) -> Result<Self, Error> {
|
||||||
let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
|
let state = try!(State::from_existing(db, parent.state_root().clone(), engine.account_start_nonce()));
|
||||||
let mut r = OpenBlock {
|
let mut r = OpenBlock {
|
||||||
@ -229,6 +231,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
engine: engine,
|
engine: engine,
|
||||||
vm_factory: vm_factory,
|
vm_factory: vm_factory,
|
||||||
last_hashes: last_hashes,
|
last_hashes: last_hashes,
|
||||||
|
dao_rescue_block_gas_limit: dao_rescue_block_gas_limit,
|
||||||
};
|
};
|
||||||
|
|
||||||
r.block.base.header.parent_hash = parent.hash();
|
r.block.base.header.parent_hash = parent.hash();
|
||||||
@ -293,6 +296,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
last_hashes: self.last_hashes.clone(), // TODO: should be a reference.
|
last_hashes: self.last_hashes.clone(), // TODO: should be a reference.
|
||||||
gas_used: self.block.receipts.last().map_or(U256::zero(), |r| r.gas_used),
|
gas_used: self.block.receipts.last().map_or(U256::zero(), |r| r.gas_used),
|
||||||
gas_limit: self.block.base.header.gas_limit.clone(),
|
gas_limit: self.block.base.header.gas_limit.clone(),
|
||||||
|
dao_rescue_block_gas_limit: if self.block.base.header.number == 1760000 { Some(self.block.base.header.gas_limit) } else { self.dao_rescue_block_gas_limit },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,6 +343,7 @@ impl<'x> OpenBlock<'x> {
|
|||||||
block: s.block,
|
block: s.block,
|
||||||
uncle_bytes: uncle_bytes,
|
uncle_bytes: uncle_bytes,
|
||||||
last_hashes: s.last_hashes,
|
last_hashes: s.last_hashes,
|
||||||
|
dao_rescue_block_gas_limit: s.dao_rescue_block_gas_limit,
|
||||||
unclosed_state: unclosed_state,
|
unclosed_state: unclosed_state,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -360,7 +365,6 @@ impl<'x> OpenBlock<'x> {
|
|||||||
LockedBlock {
|
LockedBlock {
|
||||||
block: s.block,
|
block: s.block,
|
||||||
uncle_bytes: uncle_bytes,
|
uncle_bytes: uncle_bytes,
|
||||||
last_hashes: s.last_hashes,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -386,7 +390,6 @@ impl ClosedBlock {
|
|||||||
LockedBlock {
|
LockedBlock {
|
||||||
block: self.block,
|
block: self.block,
|
||||||
uncle_bytes: self.uncle_bytes,
|
uncle_bytes: self.uncle_bytes,
|
||||||
last_hashes: self.last_hashes,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -400,6 +403,7 @@ impl ClosedBlock {
|
|||||||
engine: engine,
|
engine: engine,
|
||||||
vm_factory: vm_factory,
|
vm_factory: vm_factory,
|
||||||
last_hashes: self.last_hashes,
|
last_hashes: self.last_hashes,
|
||||||
|
dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -456,7 +460,18 @@ impl IsBlock for SealedBlock {
|
|||||||
|
|
||||||
/// Enact the block given by block header, transactions and uncles
|
/// Enact the block given by block header, transactions and uncles
|
||||||
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
#[cfg_attr(feature="dev", allow(too_many_arguments))]
|
||||||
pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Header], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result<LockedBlock, Error> {
|
pub fn enact(
|
||||||
|
header: &Header,
|
||||||
|
transactions: &[SignedTransaction],
|
||||||
|
uncles: &[Header],
|
||||||
|
engine: &Engine,
|
||||||
|
tracing: bool,
|
||||||
|
db: Box<JournalDB>,
|
||||||
|
parent: &Header,
|
||||||
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
|
vm_factory: &EvmFactory
|
||||||
|
) -> Result<LockedBlock, Error> {
|
||||||
{
|
{
|
||||||
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
if ::log::max_log_level() >= ::log::LogLevel::Trace {
|
||||||
let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce()));
|
let s = try!(State::from_existing(db.boxed_clone(), parent.state_root().clone(), engine.account_start_nonce()));
|
||||||
@ -464,7 +479,7 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, header.author().clone(), 3141562.into(), header.extra_data().clone()));
|
let mut b = try!(OpenBlock::new(engine, vm_factory, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, header.author().clone(), 3141562.into(), header.extra_data().clone()));
|
||||||
b.set_difficulty(*header.difficulty());
|
b.set_difficulty(*header.difficulty());
|
||||||
b.set_gas_limit(*header.gas_limit());
|
b.set_gas_limit(*header.gas_limit());
|
||||||
b.set_timestamp(header.timestamp());
|
b.set_timestamp(header.timestamp());
|
||||||
@ -474,22 +489,49 @@ pub fn enact(header: &Header, transactions: &[SignedTransaction], uncles: &[Head
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
pub fn enact_bytes(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result<LockedBlock, Error> {
|
pub fn enact_bytes(
|
||||||
|
block_bytes: &[u8],
|
||||||
|
engine: &Engine,
|
||||||
|
tracing: bool,
|
||||||
|
db: Box<JournalDB>,
|
||||||
|
parent: &Header,
|
||||||
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
|
vm_factory: &EvmFactory
|
||||||
|
) -> Result<LockedBlock, Error> {
|
||||||
let block = BlockView::new(block_bytes);
|
let block = BlockView::new(block_bytes);
|
||||||
let header = block.header();
|
let header = block.header();
|
||||||
enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, vm_factory)
|
enact(&header, &block.transactions(), &block.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header
|
||||||
pub fn enact_verified(block: &PreverifiedBlock, engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result<LockedBlock, Error> {
|
pub fn enact_verified(
|
||||||
|
block: &PreverifiedBlock,
|
||||||
|
engine: &Engine,
|
||||||
|
tracing: bool,
|
||||||
|
db: Box<JournalDB>,
|
||||||
|
parent: &Header,
|
||||||
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
|
vm_factory: &EvmFactory
|
||||||
|
) -> Result<LockedBlock, Error> {
|
||||||
let view = BlockView::new(&block.bytes);
|
let view = BlockView::new(&block.bytes);
|
||||||
enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, vm_factory)
|
enact(&block.header, &block.transactions, &view.uncles(), engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
/// Enact the block given by `block_bytes` using `engine` on the database `db` with given `parent` block header. Seal the block aferwards
|
||||||
pub fn enact_and_seal(block_bytes: &[u8], engine: &Engine, tracing: bool, db: Box<JournalDB>, parent: &Header, last_hashes: LastHashes, vm_factory: &EvmFactory) -> Result<SealedBlock, Error> {
|
pub fn enact_and_seal(
|
||||||
|
block_bytes: &[u8],
|
||||||
|
engine: &Engine,
|
||||||
|
tracing: bool,
|
||||||
|
db: Box<JournalDB>,
|
||||||
|
parent: &Header,
|
||||||
|
last_hashes: LastHashes,
|
||||||
|
dao_rescue_block_gas_limit: Option<U256>,
|
||||||
|
vm_factory: &EvmFactory
|
||||||
|
) -> Result<SealedBlock, Error> {
|
||||||
let header = BlockView::new(block_bytes).header_view();
|
let header = BlockView::new(block_bytes).header_view();
|
||||||
Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, vm_factory)).seal(engine, header.seal())))
|
Ok(try!(try!(enact_bytes(block_bytes, engine, tracing, db, parent, last_hashes, dao_rescue_block_gas_limit, vm_factory)).seal(engine, header.seal())))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@ -509,7 +551,7 @@ mod tests {
|
|||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap();
|
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
|
||||||
let b = b.close_and_lock();
|
let b = b.close_and_lock();
|
||||||
let _ = b.seal(engine.deref(), vec![]);
|
let _ = b.seal(engine.deref(), vec![]);
|
||||||
}
|
}
|
||||||
@ -525,7 +567,7 @@ mod tests {
|
|||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]).unwrap()
|
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap()
|
||||||
.close_and_lock().seal(engine.deref(), vec![]).unwrap();
|
.close_and_lock().seal(engine.deref(), vec![]).unwrap();
|
||||||
let orig_bytes = b.rlp_bytes();
|
let orig_bytes = b.rlp_bytes();
|
||||||
let orig_db = b.drain();
|
let orig_db = b.drain();
|
||||||
@ -533,7 +575,7 @@ mod tests {
|
|||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], &Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
|
||||||
|
|
||||||
assert_eq!(e.rlp_bytes(), orig_bytes);
|
assert_eq!(e.rlp_bytes(), orig_bytes);
|
||||||
|
|
||||||
@ -553,7 +595,7 @@ mod tests {
|
|||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], Address::zero(), 3141562.into(), vec![]).unwrap();
|
let mut open_block = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, vec![genesis_header.hash()], None, Address::zero(), 3141562.into(), vec![]).unwrap();
|
||||||
let mut uncle1_header = Header::new();
|
let mut uncle1_header = Header::new();
|
||||||
uncle1_header.extra_data = b"uncle1".to_vec();
|
uncle1_header.extra_data = b"uncle1".to_vec();
|
||||||
let mut uncle2_header = Header::new();
|
let mut uncle2_header = Header::new();
|
||||||
@ -568,7 +610,7 @@ mod tests {
|
|||||||
let mut db_result = get_temp_journal_db();
|
let mut db_result = get_temp_journal_db();
|
||||||
let mut db = db_result.take();
|
let mut db = db_result.take();
|
||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], &Default::default()).unwrap();
|
let e = enact_and_seal(&orig_bytes, engine.deref(), false, db, &genesis_header, vec![genesis_header.hash()], None, &Default::default()).unwrap();
|
||||||
|
|
||||||
let bytes = e.rlp_bytes();
|
let bytes = e.rlp_bytes();
|
||||||
assert_eq!(bytes, orig_bytes);
|
assert_eq!(bytes, orig_bytes);
|
||||||
|
@ -230,7 +230,7 @@ impl<V> Client<V> where V: Verifier {
|
|||||||
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
|
let last_hashes = self.build_last_hashes(header.parent_hash.clone());
|
||||||
let db = self.state_db.lock().unwrap().boxed_clone();
|
let db = self.state_db.lock().unwrap().boxed_clone();
|
||||||
|
|
||||||
let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, &self.vm_factory);
|
let enact_result = enact_verified(&block, engine, self.tracedb.tracing_enabled(), db, &parent, last_hashes, self.dao_rescue_block_gas_limit(), &self.vm_factory);
|
||||||
if let Err(e) = enact_result {
|
if let Err(e) = enact_result {
|
||||||
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
warn!(target: "client", "Block import failed for #{} ({})\nError: {:?}", header.number(), header.hash(), e);
|
||||||
return Err(());
|
return Err(());
|
||||||
@ -486,6 +486,7 @@ impl<V> BlockChainClient for Client<V> where V: Verifier {
|
|||||||
last_hashes: last_hashes,
|
last_hashes: last_hashes,
|
||||||
gas_used: U256::zero(),
|
gas_used: U256::zero(),
|
||||||
gas_limit: U256::max_value(),
|
gas_limit: U256::max_value(),
|
||||||
|
dao_rescue_block_gas_limit: self.dao_rescue_block_gas_limit(),
|
||||||
};
|
};
|
||||||
// that's just a copy of the state.
|
// that's just a copy of the state.
|
||||||
let mut state = self.state();
|
let mut state = self.state();
|
||||||
@ -807,6 +808,7 @@ impl<V> MiningBlockChainClient for Client<V> where V: Verifier {
|
|||||||
self.state_db.lock().unwrap().boxed_clone(),
|
self.state_db.lock().unwrap().boxed_clone(),
|
||||||
&self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"),
|
&self.chain.block_header(&h).expect("h is best block hash: so it's header must exist: qed"),
|
||||||
self.build_last_hashes(h.clone()),
|
self.build_last_hashes(h.clone()),
|
||||||
|
self.dao_rescue_block_gas_limit(),
|
||||||
author,
|
author,
|
||||||
gas_floor_target,
|
gas_floor_target,
|
||||||
extra_data,
|
extra_data,
|
||||||
|
@ -42,7 +42,7 @@ use header::{BlockNumber, Header};
|
|||||||
use transaction::{LocalizedTransaction, SignedTransaction};
|
use transaction::{LocalizedTransaction, SignedTransaction};
|
||||||
use log_entry::LocalizedLogEntry;
|
use log_entry::LocalizedLogEntry;
|
||||||
use filter::Filter;
|
use filter::Filter;
|
||||||
use views::BlockView;
|
use views::{HeaderView, BlockView};
|
||||||
use error::{ImportResult, ExecutionError};
|
use error::{ImportResult, ExecutionError};
|
||||||
use receipt::LocalizedReceipt;
|
use receipt::LocalizedReceipt;
|
||||||
use trace::LocalizedTrace;
|
use trace::LocalizedTrace;
|
||||||
@ -224,6 +224,13 @@ pub trait BlockChainClient : Sync + Send {
|
|||||||
Err(())
|
Err(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Get `Some` gas limit of block 1_760_000, or `None` if chain is not yet that long.
|
||||||
|
fn dao_rescue_block_gas_limit(&self) -> Option<U256> {
|
||||||
|
self.block_header(BlockID::Number(1_760_000))
|
||||||
|
.map(|header| HeaderView::new(&header).gas_limit())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Extended client interface used for mining
|
/// Extended client interface used for mining
|
||||||
|
@ -39,6 +39,9 @@ pub struct EnvInfo {
|
|||||||
pub last_hashes: LastHashes,
|
pub last_hashes: LastHashes,
|
||||||
/// The gas used.
|
/// The gas used.
|
||||||
pub gas_used: U256,
|
pub gas_used: U256,
|
||||||
|
|
||||||
|
/// Block gas limit at DAO rescue block #1760000 or None if not yet there.
|
||||||
|
pub dao_rescue_block_gas_limit: Option<U256>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for EnvInfo {
|
impl Default for EnvInfo {
|
||||||
@ -51,6 +54,7 @@ impl Default for EnvInfo {
|
|||||||
gas_limit: 0.into(),
|
gas_limit: 0.into(),
|
||||||
last_hashes: vec![],
|
last_hashes: vec![],
|
||||||
gas_used: 0.into(),
|
gas_used: 0.into(),
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -66,6 +70,7 @@ impl From<ethjson::vm::Env> for EnvInfo {
|
|||||||
timestamp: e.timestamp.into(),
|
timestamp: e.timestamp.into(),
|
||||||
last_hashes: (1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect(),
|
last_hashes: (1..cmp::min(number + 1, 257)).map(|i| format!("{}", number - i).as_bytes().sha3()).collect(),
|
||||||
gas_used: U256::zero(),
|
gas_used: U256::zero(),
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,6 +41,8 @@ pub struct EthashParams {
|
|||||||
pub registrar: Address,
|
pub registrar: Address,
|
||||||
/// Homestead transition block number.
|
/// Homestead transition block number.
|
||||||
pub frontier_compatibility_mode_limit: u64,
|
pub frontier_compatibility_mode_limit: u64,
|
||||||
|
/// Enable the soft-fork logic.
|
||||||
|
pub dao_rescue_soft_fork: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<ethjson::spec::EthashParams> for EthashParams {
|
impl From<ethjson::spec::EthashParams> for EthashParams {
|
||||||
@ -53,6 +55,7 @@ impl From<ethjson::spec::EthashParams> for EthashParams {
|
|||||||
block_reward: p.block_reward.into(),
|
block_reward: p.block_reward.into(),
|
||||||
registrar: p.registrar.into(),
|
registrar: p.registrar.into(),
|
||||||
frontier_compatibility_mode_limit: p.frontier_compatibility_mode_limit.into(),
|
frontier_compatibility_mode_limit: p.frontier_compatibility_mode_limit.into(),
|
||||||
|
dao_rescue_soft_fork: p.dao_rescue_soft_fork.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -102,8 +105,9 @@ impl Engine for Ethash {
|
|||||||
Schedule::new_frontier()
|
Schedule::new_frontier()
|
||||||
} else {
|
} else {
|
||||||
let mut s = Schedule::new_homestead();
|
let mut s = Schedule::new_homestead();
|
||||||
// TODO: make dependent on gaslimit > 4000000 of block 1760000.
|
if self.ethash_params.dao_rescue_soft_fork {
|
||||||
s.reject_dao_transactions = env_info.number >= 1760000;
|
s.reject_dao_transactions = env_info.dao_rescue_block_gas_limit.map(|x| x <= 4_000_000.into()).unwrap_or(false);
|
||||||
|
}
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,7 +323,7 @@ mod tests {
|
|||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap();
|
let b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
|
||||||
let b = b.close();
|
let b = b.close();
|
||||||
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
|
assert_eq!(b.state().balance(&Address::zero()), U256::from_str("4563918244f40000").unwrap());
|
||||||
}
|
}
|
||||||
@ -334,7 +338,7 @@ mod tests {
|
|||||||
spec.ensure_db_good(db.as_hashdb_mut());
|
spec.ensure_db_good(db.as_hashdb_mut());
|
||||||
let last_hashes = vec![genesis_header.hash()];
|
let last_hashes = vec![genesis_header.hash()];
|
||||||
let vm_factory = Default::default();
|
let vm_factory = Default::default();
|
||||||
let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, Address::zero(), 3141562.into(), vec![]).unwrap();
|
let mut b = OpenBlock::new(engine.deref(), &vm_factory, false, db, &genesis_header, last_hashes, None, Address::zero(), 3141562.into(), vec![]).unwrap();
|
||||||
let mut uncle = Header::new();
|
let mut uncle = Header::new();
|
||||||
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
let uncle_author = address_from_hex("ef2d6d194084c2de36e0dabfce45d046b37d1106");
|
||||||
uncle.author = uncle_author.clone();
|
uncle.author = uncle_author.clone();
|
||||||
@ -362,7 +366,8 @@ mod tests {
|
|||||||
difficulty: 0.into(),
|
difficulty: 0.into(),
|
||||||
last_hashes: vec![],
|
last_hashes: vec![],
|
||||||
gas_used: 0.into(),
|
gas_used: 0.into(),
|
||||||
gas_limit: 0.into()
|
gas_limit: 0.into(),
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(schedule.stack_limit > 0);
|
assert!(schedule.stack_limit > 0);
|
||||||
@ -374,7 +379,8 @@ mod tests {
|
|||||||
difficulty: 0.into(),
|
difficulty: 0.into(),
|
||||||
last_hashes: vec![],
|
last_hashes: vec![],
|
||||||
gas_used: 0.into(),
|
gas_used: 0.into(),
|
||||||
gas_limit: 0.into()
|
gas_limit: 0.into(),
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
});
|
});
|
||||||
|
|
||||||
assert!(!schedule.have_delegate_call);
|
assert!(!schedule.have_delegate_call);
|
||||||
|
@ -33,7 +33,12 @@ use super::spec::*;
|
|||||||
pub fn new_olympic() -> Spec { Spec::load(include_bytes!("../../res/ethereum/olympic.json")) }
|
pub fn new_olympic() -> Spec { Spec::load(include_bytes!("../../res/ethereum/olympic.json")) }
|
||||||
|
|
||||||
/// Create a new Frontier mainnet chain spec.
|
/// Create a new Frontier mainnet chain spec.
|
||||||
pub fn new_frontier() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier.json")) }
|
pub fn new_frontier(dao_rescue: bool) -> Spec {
|
||||||
|
Spec::load(match dao_rescue {
|
||||||
|
true => include_bytes!("../../res/ethereum/frontier_dao_rescue.json"),
|
||||||
|
false => include_bytes!("../../res/ethereum/frontier.json"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Create a new Frontier chain spec as though it never changes to Homestead.
|
/// Create a new Frontier chain spec as though it never changes to Homestead.
|
||||||
pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) }
|
pub fn new_frontier_test() -> Spec { Spec::load(include_bytes!("../../res/ethereum/frontier_test.json")) }
|
||||||
@ -84,7 +89,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn frontier() {
|
fn frontier() {
|
||||||
let frontier = new_frontier();
|
let frontier = new_frontier(true);
|
||||||
|
|
||||||
assert_eq!(frontier.state_root(), H256::from_str("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544").unwrap());
|
assert_eq!(frontier.state_root(), H256::from_str("d7f8974fb5ac78d9ac099b9ad5018bedc2ce0a72dad1827a1709da30580f0544").unwrap());
|
||||||
let genesis = frontier.genesis_block();
|
let genesis = frontier.genesis_block();
|
||||||
|
@ -318,7 +318,8 @@ mod tests {
|
|||||||
difficulty: 0.into(),
|
difficulty: 0.into(),
|
||||||
last_hashes: vec![],
|
last_hashes: vec![],
|
||||||
gas_used: 0.into(),
|
gas_used: 0.into(),
|
||||||
gas_limit: 0.into()
|
gas_limit: 0.into(),
|
||||||
|
dao_rescue_block_gas_limit: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -274,6 +274,7 @@ impl MinerService for Miner {
|
|||||||
last_hashes: last_hashes,
|
last_hashes: last_hashes,
|
||||||
gas_used: U256::zero(),
|
gas_used: U256::zero(),
|
||||||
gas_limit: U256::max_value(),
|
gas_limit: U256::max_value(),
|
||||||
|
dao_rescue_block_gas_limit: chain.dao_rescue_block_gas_limit(),
|
||||||
};
|
};
|
||||||
// that's just a copy of the state.
|
// that's just a copy of the state.
|
||||||
let mut state = block.state().clone();
|
let mut state = block.state().clone();
|
||||||
|
@ -222,7 +222,7 @@ impl State {
|
|||||||
let options = TransactOptions { tracing: tracing, vm_tracing: false, check_nonce: true };
|
let options = TransactOptions { tracing: tracing, vm_tracing: false, check_nonce: true };
|
||||||
let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options));
|
let e = try!(Executive::new(self, env_info, engine, vm_factory).transact(t, options));
|
||||||
|
|
||||||
let broken_dao = H256::from("7278d050619a624f84f51987149ddb439cdaadfba5966f7cfaea7ad44340a4ba");
|
let broken_dao = H256::from("6a5d24750f78441e56fec050dc52fe8e911976485b7472faac7464a176a67caa");
|
||||||
|
|
||||||
// dao attack soft fork
|
// dao attack soft fork
|
||||||
if engine.schedule(&env_info).reject_dao_transactions {
|
if engine.schedule(&env_info).reject_dao_transactions {
|
||||||
|
@ -179,6 +179,7 @@ pub fn generate_dummy_client_with_spec_and_data<F>(get_test_spec: F, block_numbe
|
|||||||
db,
|
db,
|
||||||
&last_header,
|
&last_header,
|
||||||
last_hashes.clone(),
|
last_hashes.clone(),
|
||||||
|
None,
|
||||||
author.clone(),
|
author.clone(),
|
||||||
3141562.into(),
|
3141562.into(),
|
||||||
vec![]
|
vec![]
|
||||||
|
@ -53,7 +53,8 @@ mod tests {
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit" : "0x"
|
"frontierCompatibilityModeLimit" : "0x",
|
||||||
|
"daoRescueSoftFork": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
|
@ -42,6 +42,9 @@ pub struct EthashParams {
|
|||||||
/// Homestead transition block number.
|
/// Homestead transition block number.
|
||||||
#[serde(rename="frontierCompatibilityModeLimit")]
|
#[serde(rename="frontierCompatibilityModeLimit")]
|
||||||
pub frontier_compatibility_mode_limit: Uint,
|
pub frontier_compatibility_mode_limit: Uint,
|
||||||
|
/// DAO rescue soft-fork?
|
||||||
|
#[serde(rename="daoRescueSoftFork")]
|
||||||
|
pub dao_rescue_soft_fork: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ethash engine deserialization.
|
/// Ethash engine deserialization.
|
||||||
@ -65,8 +68,9 @@ mod tests {
|
|||||||
"difficultyBoundDivisor": "0x0800",
|
"difficultyBoundDivisor": "0x0800",
|
||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar": "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit" : "0x42"
|
"frontierCompatibilityModeLimit": "0x42",
|
||||||
|
"daoRescueSoftFork": true
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
|
@ -63,7 +63,8 @@ mod tests {
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit" : "0x"
|
"frontierCompatibilityModeLimit" : "0x",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -42,12 +42,20 @@ Protocol Options:
|
|||||||
[default: $HOME/.parity/keys].
|
[default: $HOME/.parity/keys].
|
||||||
--identity NAME Specify your node's name.
|
--identity NAME Specify your node's name.
|
||||||
|
|
||||||
|
DAO-Rescue Soft-fork Options:
|
||||||
|
--help-rescue-dao Does nothing - on by default.
|
||||||
|
--dont-help-rescue-dao Votes against the DAO-rescue soft-fork, but supports
|
||||||
|
it if it is triggered anyway.
|
||||||
|
Equivalent to --gas-floor-target=3141592.
|
||||||
|
--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.
|
||||||
ACCOUNTS is a comma-delimited list of addresses.
|
ACCOUNTS is a comma-delimited list of addresses.
|
||||||
--password FILE Provide a file containing a password for unlocking
|
--password FILE Provide a file containing a password for unlocking
|
||||||
an account.
|
an account.
|
||||||
--keys-iterations NUM Specify the number of iterations to use when
|
--keys-iterations NUM Specify the number of iterations to use when
|
||||||
deriving key from the password (bigger is more
|
deriving key from the password (bigger is more
|
||||||
secure) [default: 10240].
|
secure) [default: 10240].
|
||||||
--no-import-keys Do not import keys from legacy clients.
|
--no-import-keys Do not import keys from legacy clients.
|
||||||
@ -228,6 +236,8 @@ 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_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>,
|
||||||
|
@ -75,12 +75,18 @@ impl Configuration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn gas_floor_target(&self) -> U256 {
|
pub fn gas_floor_target(&self) -> U256 {
|
||||||
let d = &self.args.flag_gas_floor_target;
|
if self.args.flag_dont_help_rescue_dao || self.args.flag_dogmatic {
|
||||||
U256::from_dec_str(d).unwrap_or_else(|_| {
|
4_700_000.into()
|
||||||
die!("{}: Invalid target gas floor given. Must be a decimal unsigned 256-bit number.", d)
|
} else {
|
||||||
})
|
let d = &self.args.flag_gas_floor_target;
|
||||||
|
U256::from_dec_str(d).unwrap_or_else(|_| {
|
||||||
|
die!("{}: Invalid target gas floor given. Must be a decimal unsigned 256-bit number.", d)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
pub fn gas_price(&self) -> U256 {
|
pub fn gas_price(&self) -> U256 {
|
||||||
match self.args.flag_gasprice.as_ref() {
|
match self.args.flag_gasprice.as_ref() {
|
||||||
Some(d) => {
|
Some(d) => {
|
||||||
@ -124,7 +130,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(),
|
"frontier" | "homestead" | "mainnet" => ethereum::new_frontier(!self.args.flag_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(|_| {
|
||||||
|
@ -183,7 +183,8 @@ const TRANSACTION_COUNT_SPEC: &'static [u8] = br#"{
|
|||||||
"durationLimit": "0x0d",
|
"durationLimit": "0x0d",
|
||||||
"blockReward": "0x4563918244F40000",
|
"blockReward": "0x4563918244F40000",
|
||||||
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
"registrar" : "0xc6d9d2cd449a754c494264e1809c50e34d64562b",
|
||||||
"frontierCompatibilityModeLimit": "0xffffffffffffffff"
|
"frontierCompatibilityModeLimit": "0xffffffffffffffff",
|
||||||
|
"daoRescueSoftFork": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -44,8 +44,8 @@
|
|||||||
//! let mut service = NetworkService::new(NetworkConfiguration::new()).unwrap();
|
//! let mut service = NetworkService::new(NetworkConfiguration::new()).unwrap();
|
||||||
//! service.start().unwrap();
|
//! service.start().unwrap();
|
||||||
//! let dir = env::temp_dir();
|
//! let dir = env::temp_dir();
|
||||||
//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(), &dir, Arc::new(Miner::default()), service.io().channel()).unwrap();
|
//! let client = Client::new(ClientConfig::default(), ethereum::new_frontier(true), &dir, Arc::new(Miner::default()), service.io().channel()).unwrap();
|
||||||
//! let miner = Miner::new(false, ethereum::new_frontier());
|
//! let miner = Miner::new(false, ethereum::new_frontier(true));
|
||||||
//! let sync = EthSync::new(SyncConfig::default(), client);
|
//! let sync = EthSync::new(SyncConfig::default(), client);
|
||||||
//! EthSync::register(&mut service, sync);
|
//! EthSync::register(&mut service, sync);
|
||||||
//! }
|
//! }
|
||||||
|
Loading…
Reference in New Issue
Block a user