diff --git a/ethereum/casper_utils.py b/ethereum/casper_utils.py index 7ab4c2baa..d8545ac19 100644 --- a/ethereum/casper_utils.py +++ b/ethereum/casper_utils.py @@ -6,7 +6,7 @@ from ethereum.transactions import Transaction from ethereum.config import Env, default_config from ethereum.state_transition import apply_transaction, apply_const_message, \ - initialize + apply_message, initialize from ethereum.block import Block, BlockHeader from ethereum.state import State from ethereum.parse_genesis_declaration import mk_basic_state @@ -56,7 +56,6 @@ def get_finalizer_code(): casper_config['METROPOLIS_FORK_BLKNUM'] = 0 casper_config['SERENITY_FORK_BLKNUM'] = 0 casper_config['HEADER_STRATEGY'] = 'casper' -casper_config['FINALIZATION'] = 'contract' casper_config['CASPER_ADDR'] = utils.int_to_addr(255) casper_config['RLP_DECODER_ADDR'] = utils.int_to_addr(253) casper_config['HASH_WITHOUT_BLOOM_ADDR'] = utils.int_to_addr(252) @@ -297,3 +296,10 @@ def casper_validate_header(state, header): raise ValueError("Validation call failed with exception") elif output: raise ValueError(output) + +def casper_post_finalize_block(state, block): + apply_message(state, + sender=state.config['SYSTEM_ENTRY_POINT'], + to=state.config['SERENITY_HEADER_POST_FINALIZER'], + data=rlp.encode(block.header)) + diff --git a/ethereum/config.py b/ethereum/config.py index 5e1123b5f..323ef6694 100644 --- a/ethereum/config.py +++ b/ethereum/config.py @@ -61,8 +61,6 @@ DAO_FORK_BLKNUM = 1920000, CHILD_DAO_LIST = map(utils.normalize_address, child_dao_list), DAO_WITHDRAWER = utils.normalize_address('0xbf4ed7b27f1d666546e30d74d50d173d20bca754'), - # Pre-seal finalization: ethereum 1.0, contract - FINALIZATION = 'ethereum1', # Default consensus strategy: ethash, poa, casper, pbft CONSENSUS_STRATEGY = 'casper', HEADER_STRATEGY = 'ethereum1', diff --git a/ethereum/consensus_strategy.py b/ethereum/consensus_strategy.py index feb0e704e..f1affd5b2 100644 --- a/ethereum/consensus_strategy.py +++ b/ethereum/consensus_strategy.py @@ -1,22 +1,28 @@ class ConsensusStrategy(object): - def __init__(self, header_validate, uncle_validate, state_initialize): + def __init__(self, header_validate, uncle_validate, block_pre_finalize, block_post_finalize, state_initialize): self.header_validate=header_validate self.uncle_validate=uncle_validate + self.block_pre_finalize=block_pre_finalize + self.block_post_finalize=block_post_finalize self.state_initialize = state_initialize def get_consensus_strategy(config): if config['CONSENSUS_STRATEGY'] in ('pow', 'ethereum1'): - from ethpow_utils import ethereum1_validate_header, ethereum1_validate_uncle + from ethpow_utils import ethereum1_validate_header, ethereum1_validate_uncle, ethereum1_pre_finalize_block, ethereum1_post_finalize_block return ConsensusStrategy( header_validate=ethereum1_validate_header, uncle_validate=ethereum1_validate_uncle, + block_pre_finalize=ethereum1_pre_finalize_block, + block_post_finalize=ethereum1_post_finalize_block, state_initialize=None ) elif config['CONSENSUS_STRATEGY'] == 'casper': - from casper_utils import casper_validate_header, casper_state_initialize + from casper_utils import casper_validate_header, casper_state_initialize, casper_post_finalize_block return ConsensusStrategy( header_validate=casper_validate_header, uncle_validate=None, + block_pre_finalize=None, + block_post_finalize=casper_post_finalize_block, state_initialize=casper_state_initialize ) else: diff --git a/ethereum/ethpow_utils.py b/ethereum/ethpow_utils.py index b3a51e0cd..8a35b30f5 100644 --- a/ethereum/ethpow_utils.py +++ b/ethereum/ethpow_utils.py @@ -95,3 +95,27 @@ def ethereum1_validate_uncle(state, uncle): raise VerificationFailed('pow mismatch') return True +def ethereum1_pre_finalize_block(state, block): + """Apply rewards and commit.""" + delta = int(state.config['BLOCK_REWARD'] + state.config['NEPHEW_REWARD'] * len(block.uncles)) + state.delta_balance(state.block_coinbase, delta) + + br = state.config['BLOCK_REWARD'] + udpf = state.config['UNCLE_DEPTH_PENALTY_FACTOR'] + + for uncle in block.uncles: + r = int(br * (udpf + uncle.number - state.block_number) // udpf) + state.delta_balance(uncle.coinbase, r) + + if state.block_number - state.config['MAX_UNCLE_DEPTH'] in state.recent_uncles: + del state.recent_uncles[state.block_number - state.config['MAX_UNCLE_DEPTH']] + +def ethereum1_post_finalize_block(state, block): + if state.is_METROPOLIS(): + state.set_storage_data(utils.normalize_address(state.config["METROPOLIS_STATEROOT_STORE"]), + state.block_number % state.config["METROPOLIS_WRAPAROUND"], + state.trie.root_hash) + state.set_storage_data(utils.normalize_address(state.config["METROPOLIS_BLOCKHASH_STORE"]), + state.block_number % state.config["METROPOLIS_WRAPAROUND"], + block.header.hash) + state.add_block_header(block.header) diff --git a/ethereum/state_transition.py b/ethereum/state_transition.py index 6a8cdf5e3..3b9af321a 100644 --- a/ethereum/state_transition.py +++ b/ethereum/state_transition.py @@ -80,45 +80,18 @@ def initialize(state, block=None): def pre_seal_finalize(state, block): - if state.config['FINALIZATION'] == 'ethereum1': - """Apply rewards and commit.""" - delta = int(state.config['BLOCK_REWARD'] + state.config['NEPHEW_REWARD'] * len(block.uncles)) - state.delta_balance(state.block_coinbase, delta) - - br = state.config['BLOCK_REWARD'] - udpf = state.config['UNCLE_DEPTH_PENALTY_FACTOR'] - - for uncle in block.uncles: - r = int(br * (udpf + uncle.number - state.block_number) // udpf) - - state.delta_balance(uncle.coinbase, r) - if state.block_number - state.config['MAX_UNCLE_DEPTH'] in state.recent_uncles: - del state.recent_uncles[state.block_number - state.config['MAX_UNCLE_DEPTH']] - elif state.config['FINALIZATION'] == 'contract': - pass - else: - raise Exception("Pre-seal finalization strategy %s not supported " % state.config['FINALIZATION']) - - state.commit() + cs = get_consensus_strategy(state.config) + if cs.block_pre_finalize: + cs.block_pre_finalize(state, block) + state.commit() def post_seal_finalize(state, block): - if state.config['FINALIZATION'] == 'ethereum1': - if state.is_METROPOLIS(): - state.set_storage_data(utils.normalize_address(state.config["METROPOLIS_STATEROOT_STORE"]), - state.block_number % state.config["METROPOLIS_WRAPAROUND"], - state.trie.root_hash) - state.set_storage_data(utils.normalize_address(state.config["METROPOLIS_BLOCKHASH_STORE"]), - state.block_number % state.config["METROPOLIS_WRAPAROUND"], - block.header.hash) - state.add_block_header(block.header) - elif state.config['FINALIZATION'].startswith('contract'): - apply_message(state, - sender=state.config['SYSTEM_ENTRY_POINT'], - to=state.config['SERENITY_HEADER_POST_FINALIZER'], - data=rlp.encode(block.header)) - state.commit() - assert len(state.journal) == 0, state.journal + cs = get_consensus_strategy(state.config) + if cs.block_post_finalize: + cs.block_post_finalize(state, block) + state.commit() + assert len(state.journal) == 0, state.journal def mk_receipt(state, logs):