Exemplo n.º 1
0
 def validator_rotation(self, slot: int, message: Message):
     self.checkpoint_rotation_count.setdefault(message.estimate.height, 0)
     name = Validator.gen_name(
         message, slot, self.config.checkpoint_interval,
         self.checkpoint_rotation_count[message.estimate.height])
     # NOTE: Now, we assume the oldest validator exit for simplicity
     oldest_validator = self.network.validator_set.validators[0]
     self.network.exit(oldest_validator)
     new_validator = Validator(name, 1.0, self.ticker)
     self.network.join(new_validator)
     self.checkpoint_rotation_count[message.estimate.height] += 1
Exemplo n.º 2
0
 def receive(self, receiver: Validator) -> List[Packet]:
     to_be_received: List[Packet] = []
     packets = self.buffer.read(receiver, self.ticker.current())
     for packet in packets:
         if receiver.message_is_to_be_pending(packet.message):
             self.buffer.add_packet_to_be_arrived(receiver, self.ticker.current() + 1, packet)
         else:
             to_be_received.append(packet)
     return to_be_received
Exemplo n.º 3
0
    def validator_rotation(self, validators: List[Validator],
                           name_prefix: str) -> List[Validator]:
        # NOTE: Now, we assume older validators exit for simplicity of visualization
        validators: List[Validator] = validators[int(self.validator_num *
                                                     self.rotation_ratio) + 1:]

        new_validators: List[Validator] = []
        for i in range(self.validator_num - len(validators)):
            validator = Validator("v{}.{}".format(name_prefix, i), 1.0,
                                  self.ticker)

            # Add genesis message FIXME: Add genesis as default
            res = validator.add_message(self.validator_set.genesis)
            assert res.is_ok(), res.value

            # Do simulation of message arrival from the start for new validator
            for past_slot in range(self.ticker.current()):
                past_message = self.broadcast_slot_to_message[past_slot]
                # Sending in past
                arrival_slot = past_slot + Delay.get(DELAY_MIN, DELAY_MAX)
                self.add_message_to_be_arrived(validator, arrival_slot,
                                               past_message)

                # Receiving in past
                messages = self.arrival_slot_to_messages.get(
                    validator, dict()).get(past_slot, [])
                for message in messages:
                    res = validator.add_message(message)
                    if not res.is_ok():
                        # If the message is not valid, skip that for the next round (assuming the reason is reordering)
                        self.add_message_to_be_arrived(validator,
                                                       past_slot + 1, message)

            new_validators.append(validator)
            validators.append(validator)

        assert len(validators) == self.validator_num
        self.validator_set.validators += new_validators
        return validators
Exemplo n.º 4
0
    def join(self, new_validator: Validator, source_validator: Optional[Validator] = None):
        assert new_validator not in self.validator_set.validators, "{} already exists".format(new_validator.name)

        if source_validator is None:
            source_validator = self.validator_set.validators[0]

        if new_validator.state.store.genesis is None:
            res = new_validator.add_message(source_validator.state.store.genesis)
            assert res.is_ok(), res.value

        # FIXME: Decide appropriate delay for each message
        for message in source_validator.state.store.messages.values():
            self.send(message, source_validator, new_validator)

        self.validator_set.validators.append(new_validator)
Exemplo n.º 5
0
 def with_equal_weight(cls, num, ticker) -> ValidatorSet:
     validators: List[Validator] = []
     for i in range(num):
         validators.append(Validator("v0.0.{}".format(i), 1.0, ticker))
     return ValidatorSet(validators)
Exemplo n.º 6
0
 def add(self, validator: Validator):
     self.validators.append(validator)
     res = validator.add_message(self.genesis)
     assert res.is_ok(), res.value
Exemplo n.º 7
0
 def with_random_weight(cls, num, ticker) -> ValidatorSet:
     validators: List[Validator] = []
     for i in range(num):
         validators.append(Validator("v{}".format(i), r.random(), ticker))
     return ValidatorSet(validators)
Exemplo n.º 8
0
def test_store():
    ticker = Ticker()
    validator = Validator("v0", 1.0, ticker)
    genesis = Message.genesis(validator)
    store = Store()
    store.add(genesis)
    b1 = Block(0, genesis.estimate.hash)
    child = Message(validator, b1,
                    Justification(store.latest_message_hashes()), 0)
    store.add(child)

    message_history = {validator: [genesis.hash, child.hash]}
    assert store.message_history == message_history

    messages = {genesis.hash: genesis, child.hash: child}
    assert store.messages == messages

    children = {genesis.hash: [child.hash]}
    assert store.children == children

    parent = {child.hash: genesis.hash}
    assert store.parent == parent

    block_to_message_in_hash = {
        genesis.estimate.hash: genesis.hash,
        child.estimate.hash: child.hash
    }
    assert store.block_to_message_in_hash == block_to_message_in_hash

    assert store.genesis == genesis

    assert store.message(child.hash) == child
    assert store.message(genesis.hash) == genesis
    assert store.message(000) is None

    latest_message_hashes = {validator: child.hash}
    assert store.latest_message_hashes() == latest_message_hashes

    latest_messages = {validator: child}
    assert store.latest_messages() == latest_messages

    assert store.parent_message(child) == genesis
    assert store.parent_message(genesis) is None

    assert store.children_messages(child) == []
    assert store.children_messages(genesis) == [child]

    assert store.parent_block(genesis.estimate) is None
    assert store.parent_block(child.estimate) == genesis.estimate

    assert store.children_blocks(child.estimate) == []
    assert store.children_blocks(genesis.estimate) == [child.estimate]

    assert store.has_children_blocks(genesis.estimate)
    assert not store.has_children_blocks(child.estimate)

    assert store.justified(genesis)
    assert store.justified(child)
    assert not store.justified(000)

    assert store.genesis_block() == genesis.estimate
Exemplo n.º 9
0
 def add_message_or_pending(self, receiver: Validator, message: Message):
     res = receiver.add_message(message)
     if not res.is_ok():
         # If the message is not valid, skip that for the next round (assuming the reason is reordering)
         self.add_message_to_be_arrived(receiver,
                                        self.ticker.current() + 1, message)