Exemple #1
0
 def tick(self):
     # Try to create a block
     # Conditions:
     # (i) you are an active validator,
     # (ii) you have not yet made a block with this parent
     if self.indices and self.chain.head_hash not in self.used_parents:
         t = self.get_timestamp()
         # Is it early enough to create the block?
         if t >= self.next_skip_timestamp and (not self.chain.head or t > self.chain.head.header.timestamp):
             print 'creating', t, self.next_skip_timestamp
             # Wrong validator; in this case, just wait for the next skip count
             if not check_skips(self.chain, self.indices, self.next_skip_count):
                 self.next_skip_count += 1
                 self.next_skip_timestamp = get_timestamp(self.chain, self.next_skip_count)
                 print 'Incrementing proposed timestamp for block %d to %d' % \
                     (self.chain.head.header.number + 1 if self.chain.head else 0, self.next_skip_timestamp)
                 return
             self.used_parents[self.chain.head_hash] = True
             # Simulated 15% chance of validator failure to make a block
             if random.random() > 0.999:
                 print 'Simulating validator failure, block %d not created' % (self.chain.head.header.number + 1 if self.chain.head else 0)
                 return
             # Make the block, make sure it's valid
             pre_dunkle_count = call_casper(self.chain.state, 'getTotalDunklesIncluded', [])
             dunkle_txs = []
             for i, u in enumerate(self.get_uncles()[:4]):
                 start_nonce = self.chain.state.get_nonce(self.address)
                 print 'start_nonce', start_nonce
                 txdata = casper_ct.encode('includeDunkle', [rlp.encode(u)])
                 dunkle_txs.append(Transaction(start_nonce + i, 0, 650000, self.chain.config['CASPER_ADDR'], 0, txdata).sign(self.key))
             for dtx in dunkle_txs[::-1]:
                 self.chain.add_transaction(dtx, force=True)
             blk = make_block(self.chain, self.key, self.randao, self.indices, self.next_skip_count)
             global global_block_counter
             global_block_counter += 1
             for dtx in dunkle_txs:
                 assert dtx in blk.transactions, (dtx, blk.transactions)
             print 'made block with timestamp %d and %d dunkles' % (blk.timestamp, len(dunkle_txs))
             assert blk.timestamp >= self.next_skip_timestamp
             assert self.chain.add_block(blk)
             self.update_head()
             post_dunkle_count = call_casper(self.chain.state, 'getTotalDunklesIncluded', [])
             assert post_dunkle_count - pre_dunkle_count == len(dunkle_txs)
             self.received_objects[blk.hash] = True
             print 'Validator %d making block %d (%s)' % (self.id, blk.header.number, blk.header.hash[:8].encode('hex'))
             self.network.broadcast(self, blk)
     # Sometimes we received blocks too early or out of order;
     # run an occasional loop that processes these
     if random.random() < 0.02:
         self.chain.process_time_queue()
         self.chain.process_parent_queue()
         self.update_head()
Exemple #2
0
 def find_my_indices(self):
     for i in range(len(validatorSizes)):
         epoch = self.chain.state.block_number // EPOCH_LENGTH
         valcount = call_casper(self.chain.state, 'getHistoricalValidatorCount', [epoch, i])
         for j in range(valcount):
             valcode = call_casper(self.chain.state, 'getValidationCode', [i, j])
             if valcode == self.validation_code:
                 self.indices = i, j
                 self.next_skip_count = 0
                 self.next_skip_timestamp = get_timestamp(self.chain, self.next_skip_count)
                 print 'In current validator set at (%d, %d)' % (i, j)
                 return
     self.indices = None
     self.next_skip_count, self.next_skip_timestamp = 0, 0
     print 'Not in current validator set'
Exemple #3
0
 def get_uncles(self):
     anc = self.chain.get_block(self.chain.get_blockhash_by_number(self.chain.state.block_number - CHECK_FOR_UNCLES_BACK))
     if anc:
         descendants = self.chain.get_descendants(anc)
     else:
         descendants = self.chain.get_descendants(self.chain.db.get('GENESIS_HASH'))
     potential_uncles = [x for x in descendants if x not in self.chain and isinstance(x, Block)]
     uncles = [x.header for x in potential_uncles if not call_casper(self.chain.state, 'isDunkleIncluded', [x.header.hash])]
     return uncles
Exemple #4
0
def generate_genesis(path=None, num_participants=1):
    privkeys = [
        utils.sha3(utils.to_string(i)) for i in range(num_participants)
    ]
    addrs = [utils.privtoaddr(k) for k in privkeys]
    deposit_sizes = [i * 500 + 500 for i in range(num_participants)]
    randaos = [RandaoManager(utils.sha3(k)) for k in privkeys]

    validators = [(generate_validation_code(a), ds * 10**18, r.get(9999), a)
                  for a, ds, r in zip(addrs, deposit_sizes, randaos)]
    s = make_casper_genesis(validators=validators,
                            alloc={a: {
                                'balance': 10**18
                            }
                                   for a in addrs},
                            timestamp=int(time.time()),
                            epoch_length=100)
    genesis_hash = apply_const_message(
        s,
        sender=casper_config['METROPOLIS_ENTRY_POINT'],
        to=casper_config['METROPOLIS_BLOCKHASH_STORE'],
        data=utils.encode_int32(0))
    genesis_number = call_casper(s, 'getBlockNumber')
    print('genesis block hash: %s' % utils.encode_hex(genesis_hash))
    print('genesis block number: %d' % genesis_number)
    print('%d validators: %r' %
          (num_participants, [utils.encode_hex(a) for a in addrs]))

    snapshot = s.to_snapshot()
    header = s.prev_headers[0]
    genesis = {
        "nonce": "0x" + utils.encode_hex(header.nonce),
        "difficulty": utils.int_to_hex(header.difficulty),
        "mixhash": "0x" + utils.encode_hex(header.mixhash),
        "coinbase": "0x" + utils.encode_hex(header.coinbase),
        "timestamp": utils.int_to_hex(header.timestamp),
        "parentHash": "0x" + utils.encode_hex(header.prevhash),
        "extraData": "0x" + utils.encode_hex(header.extra_data),
        "gasLimit": utils.int_to_hex(header.gas_limit),
        "alloc": snapshot["alloc"]
    }

    if path:
        with open(path, 'w') as f:
            json.dump(genesis,
                      f,
                      sort_keys=False,
                      indent=4,
                      separators=(',', ': '))
        print('casper genesis generated')
    else:
        return genesis
Exemple #5
0
 def get_uncles(self):
     anc = self.chain.get_block(
         self.chain.get_blockhash_by_number(self.chain.state.block_number -
                                            CHECK_FOR_UNCLES_BACK))
     if anc:
         descendants = self.chain.get_descendants(anc)
     else:
         descendants = self.chain.get_descendants(
             self.chain.db.get('GENESIS_HASH'))
     potential_uncles = [
         x for x in descendants
         if x not in self.chain and isinstance(x, Block)
     ]
     uncles = [
         x.header for x in potential_uncles if not call_casper(
             self.chain.state, 'isDunkleIncluded', [x.header.hash])
     ]
     return uncles
Exemple #6
0
def make_block(chain, key, randao, vchash, skips):
    h, _ = make_head_candidate(chain, TransactionQueue(), timestamp=get_timestamp(chain, skips))
    return sign_block(h, key, randao.get_parent(call_casper(chain.state, 'getRandao', [vchash])), vchash, skips)
Exemple #7
0
vcodes = [generate_validation_code(a) for a in addrs]
vchashes = [utils.sha3(c) for c in vcodes]
assert len(privkeys) == len(addrs) == len(randaos) == len(deposit_sizes) == len(vcodes) == len(vchashes) == NUM_PARTICIPANTS

# Creating casper contract translator
ct = get_casper_ct()
assert ct
print('Constructing genesis')
s = make_casper_genesis(validators=[(generate_validation_code(a), ds * 10**18, r.get(9999), a)
                                    for a, ds, r in zip(addrs, deposit_sizes, randaos)][:-1],
                        alloc={a: {'balance': 10**18} for a in addrs},
                        timestamp=int(time.time() - 99999),
                        epoch_length=100)
print('Genesis constructed successfully')
chains = [Chain(s.to_snapshot(), env=s.env) for i in range(NUM_PARTICIPANTS)]
withdrawal_time_1 = call_casper(chains[0].state, 'getLockDuration', [vchashes[0]])

# List of validator IDs that created each block
vids = []

# Create and sign a block
def make_block(chain, key, randao, vchash, skips):
    h, _ = make_head_candidate(chain, TransactionQueue(), timestamp=get_timestamp(chain, skips))
    return sign_block(h, key, randao.get_parent(call_casper(chain.state, 'getRandao', [vchash])), vchash, skips)

next_validator = call_casper(s, 'getValidator', [0])
print('Next validator:', next_validator.encode('hex'))
next_validator_id = vchashes.index(next_validator)
print('Next validator index:', next_validator_id)

skip_count, timestamp = get_skips_and_block_making_time(chains[0].state, next_validator)
Exemple #8
0
s.prev_headers[0].timestamp = 2
s.timestamp = 2
s.prev_headers[0].difficulty = 1
s.block_difficulty = 1
s.set_code(casper_config['CASPER_ADDR'], get_casper_code())
s.set_code(casper_config['RLP_DECODER_ADDR'], get_rlp_decoder_code())
s.set_code(casper_config['HASH_WITHOUT_BLOOM_ADDR'], get_hash_without_ed_code())
ct = get_casper_ct()
# Add all validators
for k, r, ds in zip(keys, randaos, deposit_sizes):
    a = privtoaddr(k)
    # Leave 1 eth to pay txfees
    s.set_balance(a, (ds + 1) * 10**18)
    t = Transaction(0, 0, 10**8, casper_config['CASPER_ADDR'], ds * 10**18, ct.encode('deposit', [generate_validation_code(a), r.get(9999)])).sign(k)
    success, gas, logs = apply_transaction(s, t)
s.commit()
g = s.to_snapshot()
print 'Genesis state created'

validators = [Validator(g, k, n, Env(config=casper_config), time_offset=4) for k in keys]
n.agents = validators
n.generate_peers()

for i in range(100000):
    # print 'ticking'
    n.tick()
    if i % 100 == 0:
        print 'Validator heads:', [v.chain.head.header.number if v.chain.head else None for v in validators]
        print 'Total blocks created:', casper.global_block_counter
        print 'Dunkle count:', call_casper(validators[0].chain.state, 'getTotalDunklesIncluded', [])
Exemple #9
0
 def call_casper(self, fun, args=[]):
     return call_casper(self.chain.state, fun, args)
Exemple #10
0
 def tick(self):
     # Try to create a block
     # Conditions:
     # (i) you are an active validator,
     # (ii) you have not yet made a block with this parent
     if self.indices and self.chain.head_hash not in self.used_parents:
         t = self.get_timestamp()
         # Is it early enough to create the block?
         if t >= self.next_skip_timestamp and (
                 not self.chain.head
                 or t > self.chain.head.header.timestamp):
             # Wrong validator; in this case, just wait for the next skip count
             if not check_skips(self.chain, self.indices,
                                self.next_skip_count):
                 self.next_skip_count += 1
                 self.next_skip_timestamp = get_timestamp(
                     self.chain, self.next_skip_count)
                 # print 'Incrementing proposed timestamp for block %d to %d' % \
                 #     (self.chain.head.header.number + 1 if self.chain.head else 0, self.next_skip_timestamp)
                 return
             self.used_parents[self.chain.head_hash] = True
             # Simulated 15% chance of validator failure to make a block
             if random.random() > 0.999:
                 print 'Simulating validator failure, block %d not created' % (
                     self.chain.head.header.number +
                     1 if self.chain.head else 0)
                 return
             # Make the block, make sure it's valid
             pre_dunkle_count = call_casper(self.chain.state,
                                            'getTotalDunklesIncluded', [])
             dunkle_txs = []
             for i, u in enumerate(self.get_uncles()[:4]):
                 start_nonce = self.chain.state.get_nonce(self.address)
                 txdata = casper_ct.encode('includeDunkle', [rlp.encode(u)])
                 dunkle_txs.append(
                     Transaction(start_nonce + i, 0, 650000,
                                 self.chain.config['CASPER_ADDR'], 0,
                                 txdata).sign(self.key))
             for dtx in dunkle_txs[::-1]:
                 self.chain.add_transaction(dtx, force=True)
             blk = make_block(self.chain, self.key, self.randao,
                              self.indices, self.next_skip_count)
             global global_block_counter
             global_block_counter += 1
             for dtx in dunkle_txs:
                 assert dtx in blk.transactions, (dtx, blk.transactions)
             print 'made block with timestamp %d and %d dunkles' % (
                 blk.timestamp, len(dunkle_txs))
             assert blk.timestamp >= self.next_skip_timestamp
             assert self.chain.add_block(blk)
             self.update_head()
             post_dunkle_count = call_casper(self.chain.state,
                                             'getTotalDunklesIncluded', [])
             assert post_dunkle_count - pre_dunkle_count == len(dunkle_txs)
             self.received_objects[blk.hash] = True
             print 'Validator %d making block %d (%s)' % (
                 self.id, blk.header.number,
                 blk.header.hash[:8].encode('hex'))
             self.network.broadcast(self, blk)
     # Sometimes we received blocks too early or out of order;
     # run an occasional loop that processes these
     if random.random() < 0.02:
         self.chain.process_time_queue()
         self.chain.process_parent_queue()
         self.update_head()
Exemple #11
0
n.agents = validators
n.generate_peers()
lowest_shared_height = -1
made_101_check = 0

for i in range(100000):
    # print 'ticking'
    n.tick()
    if i % 100 == 0:
        print '%d ticks passed' % i
        print 'Validator heads:', [
            v.chain.head.header.number if v.chain.head else None
            for v in validators
        ]
        print 'Total blocks created:', casper.global_block_counter
        print 'Dunkle count:', call_casper(validators[0].chain.state,
                                           'getTotalDunklesIncluded', [])
        lowest_shared_height = min([
            v.chain.head.header.number if v.chain.head else -1
            for v in validators
        ])
        if lowest_shared_height >= 101 and not made_101_check:
            made_101_check = True
            print 'Checking that withdrawn validators are inactive'
            assert len([v for v in validators
                        if v.active]) == len(validators) - 5, len(
                            [v for v in validators if v.active])
            print 'Check successful'
            break
    if i == 1:
        print 'Checking that all validators are active'
        assert len([v for v in validators if v.active]) == len(validators)
Exemple #12
0
print 'Genesis state created'

validators = [Validator(g, k, n, Env(config=casper_config), time_offset=4) for k in keys]
n.agents = validators
n.generate_peers()
lowest_shared_height = -1
made_101_check = 0

for i in range(100000):
    # print 'ticking'
    n.tick()
    if i % 100 == 0:
        print '%d ticks passed' % i
        print 'Validator heads:', [v.chain.head.header.number if v.chain.head else None for v in validators]
        print 'Total blocks created:', casper.global_block_counter
        print 'Dunkle count:', call_casper(validators[0].chain.state, 'getTotalDunklesIncluded', [])
        lowest_shared_height = min([v.chain.head.header.number if v.chain.head else -1 for v in validators])
        if lowest_shared_height >= 101 and not made_101_check:
            made_101_check = True
            print 'Checking that withdrawn validators are inactive'
            assert len([v for v in validators if v.active]) == len(validators) - 5, len([v for v in validators if v.active])
            print 'Check successful'
            break
    if i == 1:
        print 'Checking that all validators are active'
        assert len([v for v in validators if v.active]) == len(validators)
        print 'Check successful'
    if i == 2000:
        print 'Withdrawing a few validators'
        for v in validators[:5]:
            v.withdraw()
Exemple #13
0
 def call_casper(self, fun, args=[]):
     return call_casper(self.chain.state, fun, args)