def epoch_info(epoch):
    height = epoch * 50 + 49
    block = eth.chain.get_block_by_number(height)
    blockhash = block.hash
    ts = block.timestamp
    temp_state = eth.chain.mk_poststate_of_blockhash(blockhash)
    casper = tester.ABIContract(tester.State(temp_state),
                                casper_utils.casper_abi,
                                eth.chain.config['CASPER_ADDRESS'])

    ce, ese = casper.get_current_epoch(), casper.get_expected_source_epoch()
    deposit_scale_factor = casper.get_deposit_scale_factor(ce)
    storage = len(
        tester.State(temp_state).state.account_to_dict(
            eth.chain.config['CASPER_ADDRESS'])["storage"])

    info = {}
    info["number"] = height
    info["blockhash"] = encode_hex(blockhash)
    info["timestamp"] = ts
    info["difficulty"] = block.difficulty
    info["current_epoch"] = ce
    info["validators"] = validators(casper, deposit_scale_factor)
    info["lje"] = casper.get_last_justified_epoch()
    info["lfe"] = casper.get_last_finalized_epoch()
    info["votes"] = votes_and_deposits(casper, ce, ese, deposit_scale_factor)
    info["deposit_scale_factor"] = deposit_scale_factor
    info["storage"] = storage
    return info
Example #2
0
 def generate_commit_message(self, state):
     epoch = state.block_number // self.epoch_length
     # PREPARE_COMMIT_CONSISTENCY
     if self.prev_prepare_epoch < self.prev_commit_epoch and self.prev_commit_epoch < epoch:
         return None
     # Create a Casper contract which we can use to get related values
     casper = tester.ABIContract(tester.State(state),
                                 casper_utils.casper_abi,
                                 self.chain.casper_address)
     validator_index = self.get_validator_index(state)
     _e, _a, _se, _sa, _pce = self.get_recommended_casper_msg_contents(
         casper, validator_index)
     # Make the commit message
     commit_msg = casper_utils.mk_commit(validator_index, _e, _a, _pce,
                                         self.key)
     try:  # Attempt to submit the commit, to make sure that it doesn't doesn't violate DBL_PREPARE & it is justified
         casper.commit(commit_msg)
     except tester.TransactionFailed:
         log.info(
             'Commit failed! Validator {} - blockhash {} - valcode addr {}'.
             format(self.get_validator_index(state),
                    self.epoch_blockhash(state, epoch),
                    utils.encode_hex(self.valcode_addr)))
         return None
     # Save the commit as now our last commit epoch
     log.info(
         'Commit submitted: validator %d - epoch %d - prev_commit_epoch %d - hash %s'
         % (self.get_validator_index(state), epoch, self.prev_commit_epoch,
            utils.encode_hex(self.epoch_blockhash(state, epoch))))
     self.prev_commit_epoch = epoch
     return commit_msg
Example #3
0
 def get_validator_index(self, state):
     t = tester.State(state.ephemeral_clone())
     t.state.gas_limit = 9999999999
     casper = tester.ABIContract(t, casper_utils.casper_abi,
                                 self.chain.casper_address)
     if self.valcode_addr is None:
         raise Exception('Valcode address not set')
     try:
         return casper.get_validator_indexes(self.coinbase)
     except tester.TransactionFailed:
         return None
Example #4
0
 def generate_prepare_message(self, state):
     epoch = state.block_number // self.epoch_length
     # NO_DBL_PREPARE: Don't prepare if we have already
     if epoch in self.prepares:
         return None
     # Create a Casper contract which we can use to get related values
     casper = tester.ABIContract(tester.State(state),
                                 casper_utils.casper_abi,
                                 self.chain.casper_address)
     # Get the ancestry hash and source ancestry hash
     validator_index = self.get_validator_index(state)
     _e, _a, _se, _sa, _pce = self.get_recommended_casper_msg_contents(
         casper, validator_index)
     # PREPARE_COMMIT_CONSISTENCY
     if _se < self.prev_commit_epoch and self.prev_commit_epoch < epoch:
         return None
     prepare_msg = casper_utils.mk_prepare(validator_index, _e, _a, _se,
                                           _sa, self.key)
     try:  # Attempt to submit the prepare, to make sure that it is justified
         casper.prepare(prepare_msg)
     except tester.TransactionFailed:
         log.info(
             'Prepare failed! Validator {} - hash justified {} - validator start {} - valcode addr {}'
             .format(
                 self.get_validator_index(state),
                 casper.get_consensus_messages__ancestry_hash_justified(
                     epoch, _a),
                 casper.get_validators__dynasty_start(validator_index),
                 utils.encode_hex(self.valcode_addr)))
         return None
     # Save the prepare message we generated
     self.prepares[epoch] = prepare_msg
     # Save the highest source epoch we have referenced in our prepare's source epoch
     if epoch > self.prev_prepare_epoch:
         self.prev_prepare_epoch = epoch
     log.info(
         'Prepare submitted: validator %d - epoch %d - prev_commit_epoch %d - hash %s'
         % (self.get_validator_index(state), epoch, self.prev_commit_epoch,
            utils.encode_hex(self.epoch_blockhash(state, epoch))))
     return prepare_msg
Example #5
0
 def add_block(self, block):
     # ~~~ Validate ~~~~ #
     # Validate that the block should be added
     if not self.should_add_block(block):
         return False
     # ~~~ Store ~~~~ #
     # Store the block
     self.db.put(block.header.hash, rlp.encode(block))
     self.add_child(block)
     if block.number % self.config['EPOCH_LENGTH'] == 0:
         self.db.put(b'cp_subtree_score' + block.hash, 0)
     # Store the state root
     if block.header.prevhash == self.head_hash:
         temp_state = self.state.ephemeral_clone()
     else:
         temp_state = self.mk_poststate_of_blockhash(block.header.prevhash)
     apply_block(temp_state, block)
     self.db.put(b'state:' + block.header.hash, temp_state.trie.root_hash)
     # ~~~ Finality Gadget Fork Choice ~~~~ #
     old_head_chekpoint = self.head_checkpoint
     # Store the new score
     cp_hash = self.get_prev_checkpoint_hash(block.hash)
     casper = tester.ABIContract(tester.State(temp_state),
                                 casper_utils.casper_abi,
                                 self.config['CASPER_ADDRESS'])
     try:
         new_score = casper.get_main_hash_committed_frac()
         log.info('Got new score! {}'.format(new_score))
     except tester.TransactionFailed:
         new_score = 0
     if self.get_checkpoint_score(
             cp_hash) < new_score or self.get_checkpoint_score(
                 cp_hash) == 0:
         log.info(
             'Updating checkpoint score. Block num: {} - New Score: {}'.
             format(self.get_block(cp_hash).number, new_score))
         self.db.put(b'cp_score:' + cp_hash, new_score)
     # Update our view
     self.update_subtree_scores_and_child_pointers(cp_hash)
     cp = self.get_block(cp_hash)
     # Store the block as its checkpoint child if is is heavier than the current child
     p_cp = cp
     while cp is not self.genesis and self.get_checkpoint_score(
             cp.hash) == 0:
         cp = self.get_prev_checkpoint_block(cp)
     log.info(
         'Recieved block. Block num: {} - Prev cp num: {} - Prev committed cp num: {} - Head cp num: {} - Prev committed cp score: {} - Current head cp score: {}'
         .format(block.number, p_cp.number, cp.number,
                 self.head_checkpoint.number,
                 self.get_checkpoint_score(cp.hash),
                 self.get_checkpoint_score(self.checkpoint_head_hash)))
     log.info('head cp hash: {} - block prev cp hash: {}'.format(
         utils.encode_hex(cp_hash),
         utils.encode_hex(self.checkpoint_head_hash)))
     # Recompute head
     self.recompute_head_checkpoint(cp)
     # Set a new head if required
     log.info('Head cp num: {} - block prev cp num: {}'.format(
         self.head_checkpoint.number, cp.number))
     if self.head_checkpoint == cp:
         if self.head_checkpoint == old_head_chekpoint:
             log.info(
                 'Head checkpoint == old head. CP Head Num: {} - Head diff: {} - Block diff: {}'
                 .format(self.head_checkpoint.number,
                         self.get_pow_difficulty(self.head),
                         self.get_pow_difficulty(block)))
             if self.get_pow_difficulty(
                     self.head) < self.get_pow_difficulty(block):
                 self.set_head(block)
         else:
             log.info('Head checkpoint changed to cp number: {}'.format(
                 self.head_checkpoint.number))
             new_head, _ = self.find_heaviest_pow_block(
                 self.head_checkpoint)
             self.set_head(new_head)
     else:
         log.info('Skipping block: Head checkpoint is not equal to cp!')
     # Are there blocks that we received that were waiting for this block?
     # If so, process them.
     if block.header.hash in self.parent_queue:
         for _blk in self.parent_queue[block.header.hash]:
             self.add_block(_blk)
         del self.parent_queue[block.header.hash]
     return True
Example #6
0
def mk_casper_tester(validator):
    return tester.ABIContract(tester.State(validator.chain.state),
                              casper_utils.casper_abi,
                              validator.chain.casper_address)
cd docker-pyeth-dev
docker run -it --rm \
    -v $PWD/bootstrap/data/config:/root/.config/pyethapp \
    -p 30303:30303 \
    -p 30303:30303/udp \
    -p 8545:8545 \
    --name pyethapp \
    ethresearch/pyethapp-research:beta-testnet \
    pyethapp  run
# Enter console with Ctrl-C
"""

from ethereum.tools import tester
from ethereum.hybrid_casper import casper_utils
from ethereum.utils import encode_hex
casper = tester.ABIContract(tester.State(eth.chain.state),
                            casper_utils.casper_abi,
                            eth.chain.config['CASPER_ADDRESS'])


def validators(casper, deposit_scale_factor):
    validator_num = casper.get_nextValidatorIndex()
    validators = []
    for validator_index in range(1, validator_num):
        v = {}
        v["addr"] = casper.get_validators__addr(validator_index)
        v["start_dynasty"] = casper.get_validators__start_dynasty(
            validator_index)
        v["end_dynasty"] = casper.get_validators__end_dynasty(validator_index)
        v["deposit"] = casper.get_validators__deposit(
            validator_index) / 10**18 * deposit_scale_factor