Esempio n. 1
0
def test_get_networks(chain_state, token_network_address):
    orig_chain_state = deepcopy(chain_state)
    token_address = factories.make_address()
    token_network_registry_empty = TokenNetworkRegistryState(
        address=factories.make_address(), token_network_list=[])
    chain_state.identifiers_to_tokennetworkregistries[
        token_network_registry_empty.address] = token_network_registry_empty
    assert get_networks(
        chain_state=chain_state,
        token_network_registry_address=token_network_registry_empty.address,
        token_address=token_address,
    ) == (token_network_registry_empty, None)

    chain_state = orig_chain_state
    token_network = TokenNetworkState(
        address=token_network_address,
        token_address=token_address,
        network_graph=TokenNetworkGraphState(
            token_network_address=token_network_address),
    )
    token_network_registry = TokenNetworkRegistryState(
        address=factories.make_address(), token_network_list=[token_network])
    assert get_networks(
        chain_state=chain_state,
        token_network_registry_address=token_network_registry.address,
        token_address=token_address,
    ) == (None, None)
    chain_state.identifiers_to_tokennetworkregistries[
        token_network_registry.address] = token_network_registry
    assert get_networks(
        chain_state=chain_state,
        token_network_registry_address=token_network_registry.address,
        token_address=token_address,
    ) == (token_network_registry, token_network)
Esempio n. 2
0
 def wrong_amount_secret_request(self, previous_action, amount):
     assume(amount != previous_action.transfer.amount)
     self._assume_channel_opened(previous_action)
     transfer = deepcopy(previous_action.transfer)
     transfer.amount = amount
     action = self._receive_secret_request(transfer)
     self._invalid_authentic_secret_request(previous_action, action)
Esempio n. 3
0
 def copy(self) -> "StateManager[ST]":
     # The state objects must be treated as immutable, so make a copy of the
     # current state and pass the copy to the state machine to be modified.
     before_copy = time.time()
     copy_state = deepcopy(self.current_state)
     log.debug("Copied state before applying state changes",
               duration=time.time() - before_copy)
     return StateManager(self.state_transition, copy_state)
Esempio n. 4
0
def clone_state(state: T) -> T:
    # The state objects must be treated as immutable, so make a copy of the
    # current state and pass the copy to the state machine to be modified.
    before_copy = time.time()
    copy_state = deepcopy(state)
    log.debug("Copied state before applying state changes",
              duration=time.time() - before_copy)
    return copy_state
def test_contract_receive_channelnew_must_be_idempotent(channel_properties):
    block_number = 10
    block_hash = factories.make_block_hash()

    token_network_address = factories.make_address()
    token_id = factories.make_address()
    token_network_state = TokenNetworkState(
        address=token_network_address,
        token_address=token_id,
        network_graph=TokenNetworkGraphState(token_network_address),
    )

    pseudo_random_generator = random.Random()

    properties, _ = channel_properties
    channel_state1 = factories.create(properties)
    channel_state2 = deepcopy(channel_state1)

    state_change1 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state1,
        block_number=block_number,
        block_hash=block_hash,
    )

    token_network.state_transition(
        token_network_state=token_network_state,
        state_change=state_change1,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    state_change2 = ContractReceiveChannelNew(
        transaction_hash=factories.make_transaction_hash(),
        channel_state=channel_state2,
        block_number=block_number + 1,
        block_hash=factories.make_block_hash(),
    )

    # replay the ContractReceiveChannelNew state change
    iteration = token_network.state_transition(
        token_network_state=token_network_state,
        state_change=state_change2,
        block_number=block_number,
        block_hash=block_hash,
        pseudo_random_generator=pseudo_random_generator,
    )

    msg = "the channel must not have been overwritten"
    channelmap_by_id = iteration.new_state.channelidentifiers_to_channels
    assert channelmap_by_id[channel_state1.identifier] == channel_state1, msg

    channelmap_by_address = iteration.new_state.partneraddresses_to_channelidentifiers
    partner_channels_ids = channelmap_by_address[
        channel_state1.partner_state.address]
    assert channel_state1.identifier in partner_channels_ids, msg
Esempio n. 6
0
 def secret_request_with_wrong_payment_id(self, previous_action,
                                          payment_identifier):
     assume(
         payment_identifier != previous_action.transfer.payment_identifier)
     self._assume_channel_opened(previous_action)
     transfer = deepcopy(previous_action.transfer)
     transfer.payment_identifier = payment_identifier
     action = self._receive_secret_request(transfer)
     client = self._get_initiator_client(transfer)
     self._unauthentic_secret_request(action, client)
Esempio n. 7
0
 def secret_request_with_wrong_secrethash(self, previous_action, secret):
     assume(
         sha256_secrethash(secret) != sha256_secrethash(
             previous_action.transfer.secret))
     self._assume_channel_opened(previous_action)
     transfer = deepcopy(previous_action.transfer)
     transfer.secret = secret
     action = self._receive_secret_request(transfer)
     client = self._get_initiator_client(transfer)
     return self._unauthentic_secret_request(action, client)
Esempio n. 8
0
def handle_action_transfer_reroute(
    chain_state: ChainState, state_change: ActionTransferReroute
) -> TransitionResult[ChainState]:

    new_secrethash = state_change.secrethash
    current_payment_task = chain_state.payment_mapping.secrethashes_to_task[
        state_change.transfer.lock.secrethash
    ]
    chain_state.payment_mapping.secrethashes_to_task.update(
        {new_secrethash: deepcopy(current_payment_task)}
    )

    return subdispatch_to_paymenttask(chain_state, state_change, new_secrethash)
Esempio n. 9
0
    def deserialize(data: Dict) -> Any:
        """ Deserialize a dict-like object.

        If the key ``_type`` is present, import the target and deserialize via Marshmallow.
        Raises ``SerializationError`` for invalid inputs.
        """
        if not isinstance(data, Mapping):
            raise SerializationError(
                f"Can't deserialize non dict-like objects: {data}")
        if "_type" in data:
            try:
                klass = _import_type(data["_type"])
                schema = SchemaCache.get_or_create_schema(klass)
                return schema.load(deepcopy(data))
            except (ValueError, TypeError, ValidationError) as ex:
                raise SerializationError(f"Can't deserialize: {data}") from ex
        return data
Esempio n. 10
0
    def dispatch(
            self,
            state_changes: List[StateChange]) -> Tuple[ST, List[List[Event]]]:
        """ Apply the `state_change` in the current machine and return the
        resulting events.

        Args:
            state_change: An object representation of a state
            change.

        Return:
            A list of events produced by the state transition.
            It's the upper layer's responsibility to decided how to handle
            these events.
        """
        if not state_changes:
            raise ValueError(
                "dispatch called with an empty state_changes list")

        # The state objects must be treated as immutable, so make a copy of the
        # current state and pass the copy to the state machine to be modified.
        before_copy = time.time()
        next_state = deepcopy(self.current_state)
        log.debug("Copied state before applying state changes",
                  duration=time.time() - before_copy)

        # Update the current state by applying the state changes
        events: List[List[Event]] = list()
        for state_change in state_changes:
            iteration = self.state_transition(next_state, state_change)

            typecheck(iteration, TransitionResult)
            for e in iteration.events:
                typecheck(e, Event)
            typecheck(iteration.new_state, State)

            # Skipping the copy because this value is internal
            events.append(iteration.events)
            next_state = iteration.new_state

        assert next_state is not None, "State transition did not yield new state"
        self.current_state = next_state

        return iteration.new_state, events
Esempio n. 11
0
def _channel_and_transfer(num_pending_locks):
    our_model, _ = create_model(700)
    partner_model, privkey = create_model(700, num_pending_locks)
    reverse_channel_state = create_channel_from_models(partner_model, our_model, privkey)

    lock_secret = keccak(b"some secret seed")
    lock = HashTimeLockState(30, 10, sha256(lock_secret).digest())

    mediated_transfer = make_receive_transfer_mediated(
        reverse_channel_state,
        privkey,
        nonce=partner_model.next_nonce,
        transferred_amount=0,
        lock=lock,
        pending_locks=PendingLocksState(partner_model.pending_locks + [bytes(lock.encoded)]),
        locked_amount=lock.amount,
    )

    channel_state = deepcopy(reverse_channel_state)
    channel_state.our_state = reverse_channel_state.partner_state
    channel_state.partner_state = reverse_channel_state.our_state

    return channel_state, mediated_transfer
Esempio n. 12
0
def test_subdispatch_by_canonical_id(chain_state):
    our_model, _ = create_model(balance=10, num_pending_locks=1)
    partner_model, _ = create_model(balance=0, num_pending_locks=0)
    channel_state = create_channel_from_models(
        our_model, partner_model, factories.make_privatekey_bin()
    )
    canonical_identifier = channel_state.canonical_identifier
    token_network = TokenNetworkState(
        address=canonical_identifier.token_network_address,
        token_address=factories.make_address(),
        network_graph=TokenNetworkGraphState(
            token_network_address=channel_state.token_network_address
        ),
    )
    token_network.partneraddresses_to_channelidentifiers[
        partner_model.participant_address
    ] = canonical_identifier.channel_identifier
    token_network.channelidentifiers_to_channels[
        canonical_identifier.channel_identifier
    ] = channel_state
    token_network_registry = TokenNetworkRegistryState(
        address=factories.make_address(), token_network_list=[token_network]
    )
    chain_state.identifiers_to_tokennetworkregistries[
        token_network_registry.address
    ] = token_network_registry
    chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[
        canonical_identifier.token_network_address
    ] = token_network_registry.address
    # dispatching a Block will be ignored
    previous_state = deepcopy(chain_state)
    state_change = Block(
        block_number=chain_state.block_number,
        gas_limit=GAS_LIMIT,
        block_hash=chain_state.block_hash,
    )
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=canonical_identifier,
        state_change=state_change,
    )
    assert transition_result.new_state == previous_state
    assert transition_result.events == []

    state_change = ActionChannelClose(canonical_identifier=canonical_identifier)

    # dispatching for an unknown canonical_identifier will not emit events
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=chain_state.chain_id,
            token_network_address=factories.make_address(),
            channel_identifier=factories.make_channel_identifier(),
        ),
        state_change=state_change,
    )
    assert not transition_result.events, transition_result

    assert get_status(channel_state) == ChannelState.STATE_OPENED
    transition_result = subdispatch_by_canonical_id(
        chain_state=chain_state,
        canonical_identifier=canonical_identifier,
        state_change=state_change,
    )

    assert get_status(channel_state) == ChannelState.STATE_CLOSING
    assert transition_result.new_state == chain_state, transition_result
Esempio n. 13
0
def test_fees_are_updated_during_startup(raiden_network, restart_node,
                                         token_addresses, deposit,
                                         retry_timeout) -> None:
    """
    Test that the supplied fee settings are correctly forwarded to all
    channels during node startup.
    """
    app0, app1 = raiden_network

    token_address = token_addresses[0]

    def get_channel_state(app) -> NettingChannelState:
        chain_state = views.state_from_app(app)
        token_network_registry_address = app.raiden.default_registry.address
        token_network_address = views.get_token_network_address_by_token_address(
            chain_state, token_network_registry_address, token_address)
        assert token_network_address
        channel_state = views.get_channelstate_by_token_network_and_partner(
            chain_state, token_network_address, app1.raiden.address)
        assert channel_state

        return channel_state

    waiting.wait_both_channel_deposit(app0, app1,
                                      app0.raiden.default_registry.address,
                                      token_address, deposit, retry_timeout)
    # This is the imbalance penalty generated for the deposit
    # with DEFAULT_MEDIATION_PROPORTIONAL_IMBALANCE_FEE
    # once both channels have deposited the default (200) deposit
    default_imbalance_penalty = [
        (0, 1),
        (20, 0),
        (40, 0),
        (60, 0),
        (80, 0),
        (100, 0),
        (120, 0),
        (140, 0),
        (160, 0),
        (180, 0),
        (200, 0),
        (220, 0),
        (240, 0),
        (260, 0),
        (280, 0),
        (300, 0),
        (320, 0),
        (340, 0),
        (360, 0),
        (380, 0),
        (400, 1),
    ]

    # Check that the defaults are used
    channel_state = get_channel_state(app0)
    assert channel_state.fee_schedule.flat == DEFAULT_MEDIATION_FLAT_FEE
    assert channel_state.fee_schedule.proportional == DEFAULT_MEDIATION_PROPORTIONAL_FEE
    assert channel_state.fee_schedule.imbalance_penalty == default_imbalance_penalty

    original_config = deepcopy(app0.raiden.config)

    # Now restart app0, and set new flat fee for that token network
    flat_fee = FeeAmount(100)
    app0.stop()
    app0.raiden.config = deepcopy(original_config)
    app0.raiden.config.mediation_fees.token_to_flat_fee[
        token_address] = flat_fee
    restart_node(app0)

    channel_state = get_channel_state(app0)
    assert channel_state.fee_schedule.flat == flat_fee
    assert channel_state.fee_schedule.proportional == DEFAULT_MEDIATION_PROPORTIONAL_FEE
    assert channel_state.fee_schedule.imbalance_penalty == default_imbalance_penalty

    # Now restart app0, and set new proportional fee
    prop_fee = ProportionalFeeAmount(123)
    app0.stop()
    app0.raiden.config = deepcopy(original_config)
    app0.raiden.config.mediation_fees.token_to_proportional_fee[
        token_address] = prop_fee
    restart_node(app0)

    channel_state = get_channel_state(app0)
    assert channel_state.fee_schedule.flat == DEFAULT_MEDIATION_FLAT_FEE
    assert channel_state.fee_schedule.proportional == prop_fee
    assert channel_state.fee_schedule.imbalance_penalty == default_imbalance_penalty

    # Now restart app0, and set new proportional imbalance fee
    app0.stop()
    app0.raiden.config = deepcopy(original_config)
    app0.raiden.config.mediation_fees.token_to_proportional_imbalance_fee[
        token_address] = 0.05e6
    restart_node(app0)

    channel_state = get_channel_state(app0)
    assert channel_state.fee_schedule.flat == DEFAULT_MEDIATION_FLAT_FEE
    assert channel_state.fee_schedule.proportional == DEFAULT_MEDIATION_PROPORTIONAL_FEE
    # with 5% imbalance fee
    full_imbalance_penalty = [
        (0, 20),
        (20, 18),
        (40, 16),
        (60, 14),
        (80, 12),
        (100, 10),
        (120, 8),
        (140, 6),
        (160, 4),
        (180, 2),
        (200, 0),
        (220, 2),
        (240, 4),
        (260, 6),
        (280, 8),
        (300, 10),
        (320, 12),
        (340, 14),
        (360, 16),
        (380, 18),
        (400, 20),
    ]

    assert channel_state.fee_schedule.imbalance_penalty == full_imbalance_penalty