Exemple #1
0
def init_chain_and_casper():
    genesis = casper_utils.make_casper_genesis(ALLOC, EPOCH_LENGTH, 100, 0.02,
                                               0.002)
    t = tester.Chain(genesis=genesis)
    casper = tester.ABIContract(t, casper_utils.casper_abi,
                                t.chain.config['CASPER_ADDRESS'])
    return t, casper
Exemple #2
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
Exemple #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
Exemple #4
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
 def __init__(self, test_string, epoch_length, withdrawal_delay,
              base_interest_factor, base_penalty_factor):
     if test_string == '':
         raise Exception("Please pass in a valid test string")
     self.test_string = test_string
     self.genesis = casper_utils.make_casper_genesis(
         ALLOC, epoch_length, withdrawal_delay, base_interest_factor,
         base_penalty_factor)
     self.t = tester.Chain(genesis=self.genesis)
     self.casper = tester.ABIContract(
         self.t, casper_utils.casper_abi,
         self.t.chain.env.config['CASPER_ADDRESS'])
     self.saved_blocks = dict()
     self.validators = dict()
     # Register token handlers
     self.handlers = dict()
     self.handlers['B'] = self.mine_blocks
     self.handlers['J'] = self.join
     self.handlers['P'] = self.prepare
     self.handlers['C'] = self.commit
     self.handlers['S'] = self.save_block
     self.handlers['R'] = self.revert_to_block
     self.handlers['H'] = self.check_head_equals_block
     self.handlers['X'] = self.slash
Exemple #6
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
Exemple #7
0
t.gas_limit = 9999999
t.STARTGAS = 2000000
c.mine(1)

EPOCH_LENGTH = c.chain.config['EPOCH_LENGTH']

ct = abi.ContractTranslator(purity_checker_abi)
# Check that the RLP decoding library and the sig hashing library are "pure"
assert utils.big_endian_to_int(
    c.tx(t.k0, purity_checker_address, 0,
         ct.encode('submit', [viper_rlp_decoder_address]))) == 1
assert utils.big_endian_to_int(
    c.tx(t.k0, purity_checker_address, 0,
         ct.encode('submit', [sig_hasher_address]))) == 1

casper = t.ABIContract(c, casper_abi, c.chain.config['CASPER_ADDRESS'])
c.mine(1)

# Begin the test

print("Starting tests")
# Initialize the first epoch
c.mine(EPOCH_LENGTH - c.head_state.block_number)
# casper.initialize_epoch(1)
assert casper.get_nextValidatorIndex() == 0
assert casper.get_current_epoch() == 1
print("Epoch initialized")

# Deposit one validator
induct_validator(c, casper, t.k1, 200 * 10**18)
# Mine two epochs