예제 #1
0
    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
예제 #2
0
def test_block_hash():
    block = Block()
    original_block_hash = block.hash

    assert original_block_hash != b'\x00' * 32
    assert len(original_block_hash) == 32

    block = Block(slot_number=1)
    assert block.hash != original_block_hash
예제 #3
0
def test_chain():
    block = None
    parent_hash = ZERO_HASH32
    blocks = []
    for slot_number in range(1, 10):
        block = Block(slot_number=slot_number, parent_hash=parent_hash)
        blocks.append(block)
        parent_hash = block.hash

    extra_block = Block(slot_number=1000000)
    chain = Chain(head=block, blocks=blocks + [extra_block])
    assert len(chain.chain) == len(blocks)
    for block in blocks:
        assert block in chain
    assert extra_block not in chain
예제 #4
0
def explain_default_size():
    attestation_record = AttestationRecord()
    block = Block()
    crosslink_record = CrosslinkRecord()
    shard_and_committee = ShardAndCommittee()
    crystallized_state = CrystallizedState()

    attestation_record_bytes = pickle.dumps(attestation_record)
    block_bytes = pickle.dumps(block)
    crosslink_record_bytes = pickle.dumps(crosslink_record)
    shard_and_committee_bytes = pickle.dumps(shard_and_committee)
    crystallized_state_bytes = pickle.dumps(crystallized_state)

    if (verbose):
        print('{} | {}'.format(len(attestation_record_bytes), attestation_record_bytes))
        print('{} | {}'.format(len(block_bytes), block_bytes))
        print('{} | {}'.format(len(shard_and_committee_bytes), shard_and_committee_bytes))
        print('{} | {}'.format(len(crosslink_record_bytes), crosslink_record_bytes))
        print('{} | {}'.format(len(crystallized_state_bytes), crystallized_state_bytes))

    return {
        'attestationRecord': len(attestation_record_bytes),
        'block': len(block_bytes),
        'shardAndCommittee': len(shard_and_committee_bytes),
        'crosslinkRecord': len(crosslink_record_bytes),
        'validatorRecord': "N/A",
        'crystallizedState': len(crystallized_state_bytes),
    }
예제 #5
0
def test_block_by_slot_number(slot_number):
    block = Block(slot_number=slot_number)
    chain = Chain(head=block, blocks=[block])

    assert chain.get_block_by_slot_number(block.slot_number) == block
    assert chain.get_block_by_slot_number(block.slot_number + 1) is None
    assert chain.get_block_by_slot_number(-1) is None
예제 #6
0
def explain_default_size():
    attestation_record = AttestationRecord()
    block = Block()
    crosslink_record = CrosslinkRecord()
    shard_and_committee = ShardAndCommittee()
    crystallized_state = CrystallizedState()

    attestation_record_bytes = msgpack.packb(attestation_record, default=messages.encode_attestation)
    block_bytes = msgpack.packb(block, default=messages.encode_block)
    crosslink_record_bytes = msgpack.packb(crosslink_record, default=messages.encode_crosslink)
    validator_record_bytes = 0
    shard_and_committee_bytes = msgpack.packb(shard_and_committee, default=messages.encode_shard_and_committee)
    crystallized_state_bytes = msgpack.packb(crystallized_state, default=messages.encode_crystallized_state)

    if (verbose):
        print('{} | {}'.format(len(attestation_record_bytes), attestation_record_bytes))
        print('{} | {}'.format(len(block_bytes), block_bytes))
        print('{} | {}'.format(len(shard_and_committee_bytes), shard_and_committee_bytes))
        print('{} | {}'.format(len(crosslink_record_bytes), crosslink_record_bytes))
        print('{} | {}'.format(len(validator_record_bytes), validator_record_bytes))
        print('{} | {}'.format(len(crystallized_state_bytes), crystallized_state_bytes))

    return {
        'attestationRecord': len(attestation_record_bytes),
        'block': len(block_bytes),
        'shardAndCommittee': len(shard_and_committee_bytes),
        'crosslinkRecord': len(crosslink_record_bytes),
        'validatorRecord': "N/A",
        'crystallizedState': len(crystallized_state_bytes),
    }
예제 #7
0
def explain_default_size():
    """
    Show the size of the serialized object with defaults
    Note: ValidatorRecord omitted (has no defaults)
    """
    attestation_record = AttestationRecord()
    block = Block()
    crosslink_record = CrosslinkRecord()
    shard_and_committee = ShardAndCommittee()
    crystallized_state = CrystallizedState()

    attestation_record_bytes = serialize(attestation_record, type(attestation_record))
    block_bytes = serialize(block, type(block))
    crosslink_record_bytes = serialize(crosslink_record, type(crosslink_record))
    shard_and_committee_bytes = serialize(shard_and_committee, type(shard_and_committee))
    crystallized_state_bytes = serialize(crystallized_state, type(crystallized_state))

    if (verbose):
        print('{} | {}'.format(len(attestation_record_bytes), attestation_record_bytes))
        print('{} | {}'.format(len(block_bytes), block_bytes))
        print('{} | {}'.format(len(shard_and_committee_bytes), shard_and_committee_bytes))
        print('{} | {}'.format(len(crosslink_record_bytes), crosslink_record_bytes))
        print('{} | {}'.format(len(crystallized_state_bytes), crystallized_state_bytes))

    return {
        'attestationRecord': len(attestation_record_bytes),
        'block': len(block_bytes),
        'shardAndCommittee': len(shard_and_committee_bytes),
        'crosslinkRecord': len(crosslink_record_bytes),
        'validatorRecord': "N/A",
        'crystallizedState': len(crystallized_state_bytes),
    }
예제 #8
0
def test_num_attestations(expected):
    attestations = [AttestationRecord() for i in range(expected)]
    block = Block(
        attestations=attestations,
    )

    assert block.num_attestations == expected
예제 #9
0
def genesis_block():
    return Block(
        parent_hash=b'\x00' * 32,
        slot_number=0,
        randao_reveal=b'\x00' * 32,
        attestations=[],
        pow_chain_ref=b'\x00' * 32,
        active_state_root=b'\x00' * 32,
        crystallized_state_root=b'\x00' * 32,
    )
예제 #10
0
def test_num_properties():
    aggregate_vote = AggregateVote()
    block = Block(
        attestation_aggregate_sig=list(range(2)),
        shard_aggregate_votes=[aggregate_vote],
        sig=list(range(3)),
    )

    assert block.num_attestation_aggregate_sig == 2
    assert block.num_shard_aggregate_votes == 1
    assert block.num_sig == 3
예제 #11
0
def genesis_block(genesis_crystallized_state, genesis_active_state):
    return Block(parent_hash=b'\x00' * 32,
                 skip_count=0,
                 randao_reveal=b'\x00' * 32,
                 attestation_bitfield=b'',
                 attestation_aggregate_sig=[0, 0],
                 shard_aggregate_votes=[],
                 main_chain_ref=b'\x00' * 32,
                 state_hash=state_hash(genesis_crystallized_state,
                                       genesis_active_state),
                 sig=[0, 0])
예제 #12
0
 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
예제 #13
0
def get_pseudo_chain(length):
    """Get a pseudo chain, only slot_number and parent_hash are valid.
    """
    blocks = []
    for slot in range(length * 3):
        blocks.append(
            Block(
                slot_number=slot,
                parent_hash=blocks[slot - 1].hash if slot > 0 else ZERO_HASH32
            )
        )

    return blocks
예제 #14
0
def test_block_hash():
    block = Block()
    original_block_hash = block.hash

    assert original_block_hash != b'\x00' * 32
    assert len(original_block_hash) == 32

    block.sign(1)
    signed_block_hash_1 = block.hash
    assert signed_block_hash_1 != original_block_hash
    block.sign(2)
    signed_block_hash_2 = block.hash
    assert signed_block_hash_2 != original_block_hash
    assert signed_block_hash_2 != signed_block_hash_1

    block = Block(skip_count=1)
    assert block.hash != original_block_hash
    assert block.hash != signed_block_hash_1
    assert block.hash != signed_block_hash_2
예제 #15
0
def test_block_by_hash():
    block = Block()
    chain = Chain(head=block, blocks=[block])

    assert chain.get_block_by_hash(block.hash) == block
    assert chain.get_block_by_hash(b'\x35' * 32) is None
예제 #16
0
    def make_unfinished_block(parent_state,
                              parent,
                              skips,
                              attester_share=0.8,
                              crosslink_shards_and_shares=None):
        if crosslink_shards_and_shares is None:
            crosslink_shards_and_shares = []

        crystallized_state, active_state = parent_state
        parent_attestation = serialize(parent)
        indices, proposer = get_attesters_and_proposer(
            crystallized_state,
            active_state,
            skips,
            config
        )

        print('Selected indices: %r' % indices)
        print('Selected block proposer: %d' % proposer)

        # Randomly pick indices to include
        is_attesting = [random.random() < attester_share for _ in indices]
        # Attestations
        sigs = [
            bls.sign(
                parent_attestation,
                keymap[crystallized_state.active_validators[indices[i]].pubkey]
            )
            for i, attesting in enumerate(is_attesting) if attesting
        ]
        attestation_aggregate_sig = bls.aggregate_sigs(sigs)
        print('Aggregated sig')

        attestation_bitfield = get_empty_bitfield(len(indices))
        for i, attesting in enumerate(is_attesting):
            if attesting:
                attestation_bitfield = set_voted(attestation_bitfield, i)
        print('Aggregate bitfield:', bin(int.from_bytes(attestation_bitfield, 'big')))

        # Randomly pick indices to include for crosslinks
        shard_aggregate_votes = []

        # The shards that are selected to be crosslinking
        crosslink_shards = get_crosslink_shards(crystallized_state, config=config)

        for shard, crosslinker_share in crosslink_shards_and_shares:
            # Check if this shard is in the crosslink shards list
            assert shard in crosslink_shards

            print('Making crosslink in shard %d' % shard)
            indices = get_crosslink_notaries(crystallized_state, shard, crosslink_shards=crosslink_shards, config=config)
            print('Indices: %r' % indices)
            is_notarizing = [random.random() < attester_share for _ in indices]
            notary_bitfield = get_empty_bitfield(len(indices))
            for i, notarizing in enumerate(is_notarizing):
                if notarizing:
                    notary_bitfield = set_voted(notary_bitfield, i)
            print('Bitfield:', bin(int.from_bytes(notary_bitfield, '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, notarizing in enumerate(is_notarizing) if notarizing
            ]
            v = AggregateVote(
                shard_id=shard,
                shard_block_hash=shard_block_hash,
                notary_bitfield=notary_bitfield,
                aggregate_sig=list(bls.aggregate_sigs(sigs))
            )
            shard_aggregate_votes.append(v)
        print('Added %d shard aggregate votes' % len(crosslink_shards_and_shares))

        block = Block(
            parent_hash=blake(parent_attestation),
            skip_count=skips,
            randao_reveal=blake(str(random.random()).encode('utf-8')),
            attestation_bitfield=attestation_bitfield,
            attestation_aggregate_sig=list(attestation_aggregate_sig),
            shard_aggregate_votes=shard_aggregate_votes,
            main_chain_ref=b'\x00'*32,
            state_hash=b'\x00'*64
        )
        return block, proposer
예제 #17
0
def test_block_signing():
    block = Block()
    privkey = 1
    pubkey = privtopub(privkey)

    assert not block.verify(pubkey)

    block.sign(1)
    assert block.sig != [0, 0]
    assert block.verify(privtopub(1))

    block.sign(2)
    assert not block.verify(privtopub(1))
    assert block.verify(privtopub(2))

    block.skip_count = 1
    assert not block.verify(privtopub(2))
예제 #18
0
def test_head():
    block = Block()
    chain = Chain(head=block)

    assert chain.head == block
예제 #19
0
def explain_maxval_size():
    # Attestation Record
    # TODO replace oblique hash loop with correct size
    obl_hashes = []
    for i in range(0, 64):
        obl_hashes.append(helpers.MAX_BYTES)

    attestation_record = AttestationRecord(
        slot=helpers.MAX_I64,
        shard_id=helpers.MAX_I16,
        oblique_parent_hashes=obl_hashes,
        shard_block_hash=helpers.MAX_BYTES,
        attester_bitfield=helpers.MAX_BYTES,
        aggregate_sig=[helpers.MAX_256, helpers.MAX_256]
    )

    # Blocks
    # TODO: provide realistic number for attestations
    attestations = []
    for i in range(0, helpers.MAX_ATTESTATIONS):
        attestations.append(attestation_record)

    block = Block(
        parent_hash=helpers.MAX_BYTES,
        slot_number=helpers.MAX_I64,
        randao_reveal=helpers.MAX_BYTES,
        attestations=attestations,
        pow_chain_ref=helpers.MAX_BYTES,
        active_state_root=helpers.MAX_BYTES,
        crystallized_state_root=helpers.MAX_BYTES,
    )

    # Crosslink Record
    crosslink_record = CrosslinkRecord(
        hash=helpers.MAX_BYTES,
        dynasty=helpers.MAX_I64,
    )

    # Validator Record
    validator_record = ValidatorRecord(
        pubkey=helpers.MAX_256,
        withdrawal_shard=helpers.MAX_I16,
        withdrawal_address=helpers.ADDRESS_BYTES,
        randao_commitment=helpers.MAX_BYTES,
        balance=helpers.MAX_I64,
        start_dynasty=helpers.MAX_I64,
        end_dynasty=helpers.MAX_I64,
    )

    # Shard and Committee
    # TODO: replace placeholder
    committees = []
    for i in range(0, helpers.PLACEHOLDER):
        committees.append(helpers.MAX_I16)

    shard_and_committee = ShardAndCommittee(
        shard_id=helpers.MAX_I16,
        committee=committees,
    )

    # Crystallized State
    validatorlist = []
    for i in range(0, helpers.MAX_VALIDATORS):
        validatorlist.append(validator_record)

    # TODO: replace placeholder
    crosslinklist = []
    for i in range(0, helpers.PLACEHOLDER):
        crosslinklist.append(crosslink_record)

    # TODO: replace placeholder
    indices_heights = []
    for i in range(0, helpers.PLACEHOLDER):
        tmp = []
        for j in range(0, 10):
            tmp.append(shard_and_committee)
        indices_heights.append(tmp)

    crystallized_state = CrystallizedState(
        validators=validatorlist,
        indices_for_heights=indices_heights,
        last_justified_slot=helpers.MAX_I64,
        justified_streak=helpers.MAX_I64,
        last_finalized_slot=helpers.MAX_I64,
        current_dynasty=helpers.MAX_I64,
        crosslinking_start_shard=helpers.MAX_I16,
        crosslink_records=crosslinklist,
        total_deposits=helpers.MAX_256,
        dynasty_seed=helpers.MAX_BYTES,
        dynasty_seed_last_reset=helpers.MAX_I64,
        last_state_recalc=helpers.MAX_I64,
    )

    attestation_record_bytes = msgpack.packb(attestation_record, default=messages.encode_attestation)
    block_bytes = msgpack.packb(block, default=messages.encode_block)
    crosslink_record_bytes = msgpack.packb(crosslink_record, default=messages.encode_crosslink)
    validator_record_bytes = msgpack.packb(validator_record, default=messages.encode_validator_record)
    shard_and_committee_bytes = msgpack.packb(shard_and_committee, default=messages.encode_shard_and_committee)
    crystallized_state_bytes = msgpack.packb(crystallized_state, default=messages.encode_crystallized_state)

    if (verbose):
        print('{} | {}'.format(len(attestation_record_bytes), attestation_record_bytes))
        print('{} | {}'.format(len(block_bytes), block_bytes))
        print('{} | {}'.format(len(shard_and_committee_bytes), shard_and_committee_bytes))
        print('{} | {}'.format(len(crosslink_record_bytes), crosslink_record_bytes))
        print('{} | {}'.format(len(validator_record_bytes), validator_record_bytes))
        print('{} | {}'.format(len(crystallized_state_bytes), crystallized_state_bytes))

    return {
        'attestationRecord': len(attestation_record_bytes),
        'block': len(block_bytes),
        'shardAndCommittee': len(shard_and_committee_bytes),
        'crosslinkRecord': len(crosslink_record_bytes),
        'validatorRecord': len(validator_record_bytes),
        'crystallizedState': len(crystallized_state_bytes),
    }
예제 #20
0
    def make_unfinished_block(parent_state,
                              parent,
                              skips,
                              attester_share=0.8,
                              crosslink_shards_and_shares=None):
        if crosslink_shards_and_shares is None:
            crosslink_shards_and_shares = []

        crystallized_state, active_state = parent_state
        parent_attestation = serialize(parent)
        indices, proposer = get_attesters_and_proposer(crystallized_state,
                                                       active_state, skips,
                                                       config)

        print('Selected indices: %r' % indices)
        print('Selected block proposer: %d' % proposer)

        # 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_bitfield = bytearray((len(bitfield) - 1) // 8 + 1)
        for i, b in enumerate(bitfield):
            attestation_bitfield[i // 8] ^= (128 >> (i % 8)) * b
        print('Aggregate bitfield:',
              bin(int.from_bytes(attestation_bitfield, 'big')))

        # Randomly pick indices to include for crosslinks
        shard_aggregate_votes = []

        # The shards that are selected to be crosslinking
        crosslink_shards = get_crosslink_shards(crystallized_state,
                                                config=config)

        for shard, crosslinker_share in crosslink_shards_and_shares:
            # Check if this shard is in the crosslink shards list
            assert shard in crosslink_shards

            print('Making crosslink in shard %d' % shard)
            indices = get_crosslink_notaries(crystallized_state,
                                             shard,
                                             crosslink_shards=crosslink_shards,
                                             config=config)
            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_and_shares))

        block = Block(
            parent_hash=blake(parent_attestation),
            skip_count=skips,
            randao_reveal=blake(str(random.random()).encode('utf-8')),
            attestation_bitfield=attestation_bitfield,
            attestation_aggregate_sig=list(attestation_aggregate_sig),
            shard_aggregate_votes=shard_aggregate_votes,
            main_chain_ref=b'\x00' * 32,
            state_hash=b'\x00' * 64)
        return block, proposer