def test_state_transition_integration(genesis_crystallized_state, genesis_active_state, genesis_block, num_validators, epoch_length, mock_make_child): c = genesis_crystallized_state a = genesis_active_state block = genesis_block print('Generated genesis state') print('Crystallized state length:', len(serialize(genesis_crystallized_state))) print('Active state length:', len(serialize(genesis_active_state))) print('Block size:', len(serialize(genesis_block))) block2, c2, a2 = mock_make_child((c, a), block, 0, 0.8, []) t = time.time() assert compute_state_transition((c, a), block, block2) print("Normal block (basic attestation only) processed in %.4f sec" % (time.time() - t)) print('Verified a block!') block3, c3, a3 = mock_make_child((c2, a2), block2, 0, 0.8, [(0, 0.75)]) print('Verified a block with a committee!') while a3.height % epoch_length > 0: block3, c3, a3 = mock_make_child((c3, a3), block3, 0, 0.8, [(a3.height, 0.6 + 0.02 * a3.height)]) print('Height: %d' % a3.height) print('FFG bitmask:', bin(int.from_bytes(a3.ffg_voter_bitfield, 'big'))) block4, c4, a4 = mock_make_child((c3, a3), block3, 1, 0.55, []) t = time.time() assert compute_state_transition((c3, a3), block3, block4) print("Epoch transition processed in %.4f sec" % (time.time() - t))
def test_state_transition_integration(genesis_crystallized_state, genesis_active_state, genesis_block, mock_make_child, mock_make_attestations, config): c = genesis_crystallized_state a = genesis_active_state block = genesis_block print('Generated genesis state') print('Crystallized state length:', len(serialize(genesis_crystallized_state))) print('Active state length:', len(serialize(genesis_active_state))) print('Block size:', len(serialize(genesis_block))) attestations_of_genesis = mock_make_attestations( (c, a), block, attester_share=0.8 ) block2, c2, a2 = mock_make_child((c, a), block, 1, attestations_of_genesis) assert block2.slot_number == 1 assert len(block2.attestations) == len(attestations_of_genesis) assert block2.crystallized_state_root == block.crystallized_state_root assert block2.active_state_root != b'\x00'*32 t = time.time() assert compute_state_transition((c, a), block, block2, config=config) print( "Normal block with %s attestations of size %s processed in %.4f sec" % ( len(attestations_of_genesis), len(c.indices_for_slots[attestations_of_genesis[0].slot][0].committee), (time.time() - t)) ) print('Verified a block!') attestations_of_2 = mock_make_attestations( (c2, a2), block2, attester_share=0.8 ) cycle_transition_slot = c2.last_state_recalc + config['cycle_length'] block3, c3, a3 = mock_make_child( (c2, a2), block2, cycle_transition_slot, attestations_of_2 ) t = time.time() assert compute_state_transition((c2, a2), block2, block3, config=config) print("Cycle transition processed in %.4f sec" % (time.time() - t))
def mock_make_child(parent_state, parent, slot_number, attestations=None): if attestations is None: attestations = [] crystallized_state, active_state = parent_state block = Block(parent_hash=parent.hash, slot_number=slot_number, randao_reveal=blake( str(random.random()).encode('utf-8')), attestations=attestations, pow_chain_ref=b'\x00' * 32, active_state_root=b'\x00' * 32, crystallized_state_root=b'\x00' * 32) print('Generated preliminary block header') new_crystallized_state, new_active_state = compute_state_transition( (crystallized_state, active_state), parent, block, config=config) print('Calculated state transition') if crystallized_state == new_crystallized_state: block.crystallized_state_root = parent.crystallized_state_root else: block.crystallized_state_root = blake( serialize(crystallized_state)) block.active_state_root = blake(serialize(active_state)) return block, new_crystallized_state, new_active_state
def mock_make_child(parent_state, parent, skips, attester_share=0.8, crosslink_shards=[]): crystallized_state, active_state = parent_state block, proposer = make_unfinished_block(parent_state, parent, skips, attester_share, crosslink_shards) print('Generated preliminary block header') new_crystallized_state, new_active_state = compute_state_transition( (crystallized_state, active_state), parent, block, verify_sig=False, config=config) print('Calculated state transition') if crystallized_state == new_crystallized_state: block.state_hash = blake(parent.state_hash[:32] + blake(serialize(new_active_state))) else: block.state_hash = blake( blake(serialize(new_crystallized_state)) + blake(serialize(new_active_state))) # Main signature block.sign( keymap[crystallized_state.active_validators[proposer].pubkey]) print('Signed') return block, new_crystallized_state, new_active_state
def mock_make_child(parent_state, parent, skips, attester_share=0.8, crosslink_shards=[]): crystallized_state, active_state = parent_state parent_attestation = serialize(parent) indices, main_signer = get_attesters_and_signer(crystallized_state, active_state, skips) print('Selected indices: %r' % indices) print('Selected main signer: %d' % main_signer) # Randomly pick indices to include bitfield = [1 if random.random() < attester_share else 0 for i in indices] # Attestations sigs = [bls.sign(parent_attestation, keymap[crystallized_state.active_validators[indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i]] attestation_aggregate_sig = bls.aggregate_sigs(sigs) print('Aggregated sig') attestation_bitmask = bytearray((len(bitfield)-1) // 8 + 1) for i, b in enumerate(bitfield): attestation_bitmask[i//8] ^= (128 >> (i % 8)) * b print('Aggregate bitmask:', bin(int.from_bytes(attestation_bitmask, 'big'))) # Randomly pick indices to include for crosslinks shard_aggregate_votes = [] for shard, crosslinker_share in crosslink_shards: print('Making crosslink in shard %d' % shard) indices = get_shard_attesters(crystallized_state, shard) print('Indices: %r' % indices) bitfield = [1 if random.random() < crosslinker_share else 0 for i in indices] bitmask = bytearray((len(bitfield)+7) // 8) for i, b in enumerate(bitfield): bitmask[i//8] ^= (128 >> (i % 8)) * b print('Bitmask:', bin(int.from_bytes(bitmask, 'big'))) shard_block_hash = blake(bytes([shard])) crosslink_attestation_hash = get_crosslink_aggvote_msg(shard, shard_block_hash, crystallized_state) sigs = [bls.sign(crosslink_attestation_hash, keymap[crystallized_state.active_validators[indices[i]].pubkey]) for i in range(len(indices)) if bitfield[i]] v = AggregateVote(shard_id=shard, shard_block_hash=shard_block_hash, signer_bitmask=bitmask, aggregate_sig=list(bls.aggregate_sigs(sigs))) shard_aggregate_votes.append(v) print('Added %d shard aggregate votes' % len(crosslink_shards)) # State calculations o = Block(parent_hash=blake(parent_attestation), skip_count=skips, randao_reveal=blake(str(random.random()).encode('utf-8')), attestation_bitmask=attestation_bitmask, attestation_aggregate_sig=list(attestation_aggregate_sig), shard_aggregate_votes=shard_aggregate_votes, main_chain_ref=b'\x00'*32, state_hash=b'\x00'*64) print('Generated preliminary block header') new_crystallized_state, new_active_state = \ compute_state_transition((crystallized_state, active_state), parent, o, verify_sig=False) print('Calculated state transition') if crystallized_state == new_crystallized_state: o.state_hash = blake(parent.state_hash[:32] + blake(serialize(new_active_state))) else: o.state_hash = blake(blake(serialize(new_crystallized_state)) + blake(serialize(new_active_state))) # Main signature o.sign(keymap[crystallized_state.active_validators[main_signer].pubkey]) print('Signed') return o, new_crystallized_state, new_active_state