示例#1
0
文件: node.py 项目: sekmet/raiden
def handle_block(chain_state: ChainState, state_change: Block) -> TransitionResult[ChainState]:
    block_number = state_change.block_number
    chain_state.block_number = block_number
    chain_state.block_hash = state_change.block_hash

    # Subdispatch Block state change
    channels_result = subdispatch_to_all_channels(
        chain_state=chain_state,
        state_change=state_change,
        block_number=block_number,
        block_hash=chain_state.block_hash,
    )
    transfers_result = subdispatch_to_all_lockedtransfers(chain_state, state_change)
    events = channels_result.events + transfers_result.events
    return TransitionResult(chain_state, events)
示例#2
0
def handle_update_transport_authdata(
    chain_state: ChainState,
    state_change: ActionUpdateTransportAuthData,
) -> TransitionResult[ChainState]:
    assert chain_state is not None, 'chain_state must be set'
    chain_state.last_transport_authdata = state_change.auth_data
    return TransitionResult(chain_state, list())
示例#3
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            pseudo_random_generator=self.random,
            block_number=self.block_number,
            block_hash=self.block_hash,
            our_address=self.address,
            chain_id=factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.make_address()
        self.token_id = factories.make_address()
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id,
            [self.token_network_state],
        )

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        return self.new_channel_with_transaction()
示例#4
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            pseudo_random_generator=self.random,
            block_number=self.block_number,
            block_hash=self.block_hash,
            our_address=self.address,
            chain_id=factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.UNIT_TOKEN_NETWORK_ADDRESS
        self.token_id = factories.UNIT_TOKEN_ADDRESS
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id, [self.token_network_state])

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        self.chain_state.tokennetworkaddresses_to_paymentnetworkaddresses[
            self.token_network_id] = self.payment_network_id
        channels = [
            self.new_channel_with_transaction()
            for _ in range(self.initial_number_of_channels)
        ]
        return multiple(*channels)
示例#5
0
文件: node.py 项目: tarun1475/raiden
def handle_chain_init(chain_state, state_change):
    chain_state = ChainState(
        state_change.pseudo_random_generator,
        state_change.block_number,
        state_change.chain_id,
    )
    events = list()
    return TransitionResult(chain_state, events)
示例#6
0
文件: fixtures.py 项目: onyb/raiden
def chain_state(our_address):
    block_number = 1

    return ChainState(
        random.Random(),
        block_number,
        our_address,
        UNIT_CHAIN_ID,
    )
示例#7
0
def chain_state(our_address):
    block_number = BlockNumber(1)

    return ChainState(
        pseudo_random_generator=random.Random(),
        block_number=block_number,
        block_hash=factories.make_block_hash(),
        our_address=our_address,
        chain_id=UNIT_CHAIN_ID,
    )
示例#8
0
def handle_node_change_network_state(
        chain_state: ChainState,
        state_change: ActionChangeNodeNetworkState,
) -> TransitionResult:
    events = list()

    node_address = state_change.node_address
    network_state = state_change.network_state
    chain_state.nodeaddresses_to_networkstates[node_address] = network_state

    return TransitionResult(chain_state, events)
示例#9
0
def handle_node_change_network_state(
        chain_state: ChainState,
        state_change: ActionChangeNodeNetworkState,
) -> TransitionResult:
    events = list()

    node_address = state_change.node_address
    network_state = state_change.network_state
    chain_state.nodeaddresses_to_networkstates[node_address] = network_state

    return TransitionResult(chain_state, events)
示例#10
0
文件: node.py 项目: zhaohaijun/raiden
def handle_chain_init(
    chain_state: ChainState,
    state_change: ActionInitChain,
) -> TransitionResult:
    chain_state = ChainState(
        state_change.pseudo_random_generator,
        state_change.block_number,
        state_change.our_address,
        state_change.chain_id,
    )
    events = list()
    return TransitionResult(chain_state, events)
示例#11
0
def handle_new_payment_network(
        chain_state: ChainState,
        state_change: ContractReceiveNewPaymentNetwork,
) -> TransitionResult:
    events = list()

    payment_network = state_change.payment_network
    payment_network_identifier = payment_network.address
    if payment_network_identifier not in chain_state.identifiers_to_paymentnetworks:
        chain_state.identifiers_to_paymentnetworks[payment_network_identifier] = payment_network

    return TransitionResult(chain_state, events)
示例#12
0
def handle_new_payment_network(
        chain_state: ChainState,
        state_change: ContractReceiveNewPaymentNetwork,
) -> TransitionResult:
    events = list()

    payment_network = state_change.payment_network
    payment_network_identifier = payment_network.address
    if payment_network_identifier not in chain_state.identifiers_to_paymentnetworks:
        chain_state.identifiers_to_paymentnetworks[payment_network_identifier] = payment_network

    return TransitionResult(chain_state, events)
示例#13
0
文件: node.py 项目: sekmet/raiden
def handle_contract_receive_new_token_network_registry(
    chain_state: ChainState, state_change: ContractReceiveNewTokenNetworkRegistry
) -> TransitionResult[ChainState]:
    events: List[Event] = list()

    token_network_registry = state_change.token_network_registry
    token_network_registry_address = TokenNetworkRegistryAddress(token_network_registry.address)
    if token_network_registry_address not in chain_state.identifiers_to_tokennetworkregistries:
        chain_state.identifiers_to_tokennetworkregistries[
            token_network_registry_address
        ] = token_network_registry

    return TransitionResult(chain_state, events)
示例#14
0
def handle_chain_init(
        chain_state: ChainState,
        state_change: ActionInitChain) -> TransitionResult[ChainState]:
    if chain_state is None:
        chain_state = ChainState(
            pseudo_random_generator=state_change.pseudo_random_generator,
            block_number=state_change.block_number,
            block_hash=state_change.block_hash,
            our_address=state_change.our_address,
            chain_id=state_change.chain_id,
        )
    events: List[Event] = list()
    return TransitionResult(chain_state, events)
示例#15
0
文件: mocks.py 项目: sekmet/raiden
    def __init__(self,
                 message_handler=None,
                 state_transition=None,
                 private_key=None):
        if private_key is None:
            self.privkey, self.address = factories.make_privkey_address()
        else:
            self.privkey = private_key
            self.address = privatekey_to_address(private_key)

        self.rpc_client = MockJSONRPCClient(self.address)
        self.proxy_manager = MockProxyManager(node_address=self.address)
        self.signer = LocalSigner(self.privkey)

        self.message_handler = message_handler
        self.routing_mode = RoutingMode.PRIVATE
        self.config = RaidenConfig(chain_id=self.rpc_client.chain_id,
                                   environment_type=Environment.DEVELOPMENT)

        self.default_user_deposit = Mock()
        self.default_registry = Mock()
        self.default_registry.address = factories.make_address()
        self.default_one_to_n_address = factories.make_address()
        self.default_msc_address = factories.make_address()

        self.targets_to_identifiers_to_statuses: Dict[Address,
                                                      dict] = defaultdict(dict)
        self.route_to_feedback_token: dict = {}

        if state_transition is None:
            state_transition = node.state_transition

        serializer = JSONSerializer()
        initial_state = ChainState(
            pseudo_random_generator=random.Random(),
            block_number=BlockNumber(0),
            block_hash=factories.make_block_hash(),
            our_address=self.rpc_client.address,
            chain_id=self.rpc_client.chain_id,
        )
        wal = WriteAheadLog(
            state=initial_state,
            storage=SerializedSQLiteStorage(":memory:", serializer),
            state_transition=state_transition,
        )

        self.wal = wal
        self.transport = Mock()
示例#16
0
    def _initialize_monitoring_services_queue(self, chain_state: ChainState):
        """Send the monitoring requests for all current balance proofs.

        Note:
            The node must always send the *received* balance proof to the
            monitoring service, *before* sending its own locked transfer
            forward. If the monitoring service is updated after, then the
            following can happen:

            For a transfer A-B-C where this node is B

            - B receives T1 from A and processes it
            - B forwards its T2 to C
            * B crashes (the monitoring service is not updated)

            For the above scenario, the monitoring service would not have the
            latest balance proof received by B from A available with the lock
            for T1, but C would. If the channel B-C is closed and B does not
            come back online in time, the funds for the lock L1 can be lost.

            During restarts the rationale from above has to be replicated.
            Because the initialization code *is not* the same as the event
            handler. This means the balance proof updates must be done prior to
            the processing of the message queues.
        """
        msg = (
            'Transport was started before the monitoring service queue was updated. '
            'This can lead to safety issue. node:{self!r}')
        assert not self.transport, msg

        msg = (
            'The node state was not yet recovered, cant read balance proofs. node:{self!r}'
        )
        assert self.wal, msg

        current_balance_proofs = views.detect_balance_proof_change(
            old_state=ChainState(
                pseudo_random_generator=chain_state.pseudo_random_generator,
                block_number=GENESIS_BLOCK_NUMBER,
                block_hash=constants.EMPTY_HASH,
                our_address=chain_state.our_address,
                chain_id=chain_state.chain_id,
            ),
            current_state=chain_state,
        )
        for balance_proof in current_balance_proofs:
            update_services_from_balance_proof(self, chain_state,
                                               balance_proof)
示例#17
0
    def initialize_all(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.block_hash = factories.make_block_hash()
        self.random = random

        self.token_network_address = factories.UNIT_TOKEN_NETWORK_ADDRESS
        self.token_id = factories.UNIT_TOKEN_ADDRESS
        self.token_network_state = TokenNetworkState(
            address=self.token_network_address,
            token_address=self.token_id,
            network_graph=TokenNetworkGraphState(self.token_network_address),
        )

        self.token_network_registry_address = factories.make_token_network_registry_address()
        self.token_network_registry_state = TokenNetworkRegistryState(
            self.token_network_registry_address, [self.token_network_state]
        )

        channels = []
        for _ in range(self.number_of_clients):
            private_key, address = factories.make_privkey_address()
            self.address_to_privkey[address] = private_key

            chain_state = ChainState(
                pseudo_random_generator=self.random,
                block_number=self.block_number,
                block_hash=self.block_hash,
                our_address=address,
                chain_id=factories.UNIT_CHAIN_ID,
            )
            chain_state.identifiers_to_tokennetworkregistries[
                self.token_network_registry_address
            ] = self.token_network_registry_state

            chain_state.tokennetworkaddresses_to_tokennetworkregistryaddresses[
                self.token_network_address
            ] = self.token_network_registry_address

            self.address_to_client[address] = Client(chain_state=chain_state)

            channels.extend(
                self.new_channel_with_transaction(client_address=address)
                for _ in range(self.initial_number_of_channels)
            )

        return multiple(*channels)
示例#18
0
def inplace_delete_message_queue(
    chain_state: ChainState,
    state_change: Union[ReceiveDelivered, ReceiveProcessed],
    queueid: QueueIdentifier,
) -> None:
    """ Filter messages from queue, if the queue becomes empty, cleanup the queue itself. """
    queue = chain_state.queueids_to_queues.get(queueid)
    if not queue:
        return

    inplace_delete_message(message_queue=queue, state_change=state_change)

    if len(queue) == 0:
        del chain_state.queueids_to_queues[queueid]
    else:
        chain_state.queueids_to_queues[queueid] = queue
示例#19
0
    def initialize(self, block_number, random, random_seed):
        self.random_seed = random_seed

        self.block_number = block_number
        self.random = random
        self.private_key, self.address = factories.make_privkey_address()

        self.chain_state = ChainState(
            self.random,
            self.block_number,
            self.address,
            factories.UNIT_CHAIN_ID,
        )

        self.token_network_id = factories.make_address()
        self.token_id = factories.make_address()
        self.token_network_state = TokenNetworkState(self.token_network_id,
                                                     self.token_id)

        self.payment_network_id = factories.make_payment_network_identifier()
        self.payment_network_state = PaymentNetworkState(
            self.payment_network_id,
            [self.token_network_state],
        )

        self.chain_state.identifiers_to_paymentnetworks[
            self.payment_network_id] = self.payment_network_state

        self.channels = list()

        for partner_address in self.channels_with:
            channel = factories.make_channel(
                our_balance=1000,
                partner_balance=1000,
                token_network_identifier=self.token_network_id,
                our_address=self.address,
                partner_address=partner_address,
            )
            channel_new_state_change = ContractReceiveChannelNew(
                factories.make_transaction_hash(),
                self.token_network_id,
                channel,
                self.block_number,
            )
            node.state_transition(self.chain_state, channel_new_state_change)

            self.channels.append(channel)
示例#20
0
def inplace_delete_message_queue(
        chain_state: ChainState,
        state_change: StateChange,
        queueid: QueueIdentifier,
):
    """ Filter messages from queue, if the queue becomes empty, cleanup the queue itself. """
    queue = chain_state.queueids_to_queues.get(queueid)
    if not queue:
        return

    inplace_delete_message(
        queue,
        state_change,
    )

    if len(queue) == 0:
        del chain_state.queueids_to_queues[queueid]
    else:
        chain_state.queueids_to_queues[queueid] = queue
示例#21
0
def handle_block(
        chain_state: ChainState,
        state_change: Block,
) -> TransitionResult:
    block_number = state_change.block_number
    chain_state.block_number = block_number

    # Subdispatch Block state change
    channels_result = subdispatch_to_all_channels(
        chain_state,
        state_change,
        block_number,
    )
    transfers_result = subdispatch_to_all_lockedtransfers(
        chain_state,
        state_change,
    )
    events = channels_result.events + transfers_result.events
    return TransitionResult(chain_state, events)
示例#22
0
def inplace_delete_message_queue(
        chain_state: ChainState,
        state_change: StateChange,
        queueid: QueueIdentifier,
):
    """ Filter messages from queue, if the queue becomes empty, cleanup the queue itself. """
    queue = chain_state.queueids_to_queues.get(queueid)
    if not queue:
        return

    inplace_delete_message(
        queue,
        state_change,
    )

    if len(queue) == 0:
        del chain_state.queueids_to_queues[queueid]
    else:
        chain_state.queueids_to_queues[queueid] = queue
示例#23
0
def handle_delivered(chain_state: ChainState,
                     state_change: ReceiveDelivered) -> TransitionResult:
    # TODO: improve the complexity of this algorithm
    queueids_to_remove = []
    for queueid, queue in chain_state.queueids_to_queues.items():
        if queueid.channel_identifier == CHANNEL_IDENTIFIER_GLOBAL_QUEUE:
            filtered_queue = [
                message for message in queue if
                message.message_identifier != state_change.message_identifier
            ]

            if not filtered_queue:
                queueids_to_remove.append(queueid)
            else:
                chain_state.queueids_to_queues[queueid] = filtered_queue

    for queueid in queueids_to_remove:
        del chain_state.queueids_to_queues[queueid]

    return TransitionResult(chain_state, [])
示例#24
0
def handle_node_change_network_state(
    chain_state: ChainState,
    state_change: ActionChangeNodeNetworkState,
) -> TransitionResult[ChainState]:
    events: List[Event] = list()

    node_address = state_change.node_address
    network_state = state_change.network_state
    chain_state.nodeaddresses_to_networkstates[node_address] = network_state

    for secrethash, subtask in chain_state.payment_mapping.secrethashes_to_task.items(
    ):
        result = subdispatch_mediatortask(
            chain_state=chain_state,
            state_change=state_change,
            secrethash=secrethash,
            token_network_identifier=subtask.token_network_identifier,
        )
        events.extend(result.events)

    return TransitionResult(chain_state, events)
示例#25
0
文件: node.py 项目: sekmet/raiden
def handle_action_change_node_network_state(
    chain_state: ChainState, state_change: ActionChangeNodeNetworkState
) -> TransitionResult[ChainState]:
    events: List[Event] = list()

    node_address = state_change.node_address
    network_state = state_change.network_state
    chain_state.nodeaddresses_to_networkstates[node_address] = network_state

    for secrethash, subtask in list(chain_state.payment_mapping.secrethashes_to_task.items()):
        # This typecheck would not have been needed if token_network_address, a common attribute
        # for all TransferTasks was part of the TransferTasks superclass.
        typecheck(subtask, (InitiatorTask, MediatorTask, TargetTask))
        result = subdispatch_mediatortask(
            chain_state=chain_state,
            state_change=state_change,
            token_network_address=subtask.token_network_address,
            secrethash=secrethash,
        )
        events.extend(result.events)

    return TransitionResult(chain_state, events)
示例#26
0
def test_detect_balance_proof_change():
    prng = random.Random()
    block_hash = factories.make_block_hash()
    old = ChainState(
        pseudo_random_generator=prng,
        block_number=1,
        block_hash=block_hash,
        our_address=2,
        chain_id=3,
    )
    new = ChainState(
        pseudo_random_generator=prng,
        block_number=1,
        block_hash=block_hash,
        our_address=2,
        chain_id=3,
    )

    def diff():
        return list(detect_balance_proof_change(old, new))

    assert len(diff()) == 0

    payment_network = PaymentNetworkState(b'x', [])
    payment_network_copy = deepcopy(payment_network)
    new.identifiers_to_paymentnetworks['a'] = payment_network
    assert len(diff()) == 0

    token_network = TokenNetworkState(b'a', b'a')
    token_network_copy = deepcopy(token_network)
    payment_network.tokenidentifiers_to_tokennetworks['a'] = token_network
    assert len(diff()) == 0

    channel = NettingChannelState(
        canonical_identifier=factories.make_canonical_identifier(),
        token_address=b'a',
        payment_network_identifier=1,
        reveal_timeout=1,
        settle_timeout=2,
        mediation_fee=0,
        our_state=None,
        partner_state=None,
        open_transaction=TransactionExecutionStatus(result='success'),
        settle_transaction=None,
        update_transaction=None,
        close_transaction=None,
    )
    channel_copy = deepcopy(channel)
    token_network.channelidentifiers_to_channels['a'] = channel
    our_state = NettingChannelEndState(address=b'b', balance=1)
    our_state_copy = deepcopy(our_state)
    partner_state = NettingChannelEndState(address=b'a', balance=0)
    partner_state_copy = deepcopy(partner_state)

    channel.our_state = our_state
    channel.partner_state = partner_state
    assert len(diff()) == 0

    balance_proof = object()
    partner_state.balance_proof = balance_proof
    assert len(diff()) == 1

    old.identifiers_to_paymentnetworks['a'] = payment_network_copy
    assert len(diff()) == 1

    payment_network_copy.tokenidentifiers_to_tokennetworks[
        'a'] = token_network_copy
    assert len(diff()) == 1

    token_network_copy.channelidentifiers_to_channels['a'] = channel_copy
    channel_copy.partner_state = partner_state_copy
    assert len(diff()) == 1

    channel_copy.partner_state.balance_proof = balance_proof
    assert len(diff()) == 0

    channel_copy.partner_state.balance_proof = object()
    assert len(diff()) == 1
    assert diff() == [balance_proof]

    # check our_state BP changes
    channel_copy.partner_state.balance_proof = balance_proof
    assert len(diff()) == 0

    channel.our_state.balance_proof = object()
    channel_copy.our_state = our_state_copy
    assert len(diff()) == 1
    assert diff() == [channel.our_state.balance_proof]

    channel_copy.our_state.balance_proof = channel.our_state.balance_proof
    assert len(diff()) == 0
示例#27
0
def handle_update_transport_authdata(
        chain_state: ChainState,
        state_change: ActionUpdateTransportAuthData,
) -> TransitionResult:
    chain_state.last_transport_authdata = state_change.auth_data
    return TransitionResult(chain_state, list())
示例#28
0
def handle_update_transport_synctoken(
    chain_state: ChainState,
    state_change: ActionUpdateTransportSyncToken,
) -> TransitionResult:
    chain_state.last_transport_synctoken = state_change.sync_token
    return TransitionResult(chain_state, list())
示例#29
0
def handle_update_transport_authdata(
        chain_state: ChainState,
        state_change: ActionUpdateTransportAuthData,
) -> TransitionResult:
    chain_state.last_transport_authdata = state_change.auth_data
    return TransitionResult(chain_state, list())
示例#30
0
def test_detect_balance_proof_change():
    prng = random.Random()

    block_hash = make_block_hash()
    our_address = make_address()
    empty_chain = ChainState(
        pseudo_random_generator=prng,
        block_number=1,
        block_hash=block_hash,
        our_address=our_address,
        chain_id=3,
    )

    assert empty(detect_balance_proof_change(empty_chain,
                                             empty_chain)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(empty_chain,
                                    deepcopy(empty_chain))), MSG_NO_CHANGE

    token_network_registry_address = make_address()
    chain_with_registry_no_bp = deepcopy(empty_chain)
    chain_with_registry_no_bp.identifiers_to_tokennetworkregistries[
        token_network_registry_address] = TokenNetworkRegistryState(
            token_network_registry_address, [])

    assert empty(
        detect_balance_proof_change(empty_chain,
                                    chain_with_registry_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(
            chain_with_registry_no_bp,
            deepcopy(chain_with_registry_no_bp))), MSG_NO_CHANGE

    token_network_address = make_address()
    token_address = make_address()

    chain_with_token_network_no_bp = deepcopy(chain_with_registry_no_bp)
    chain_with_token_network_no_bp.identifiers_to_tokennetworkregistries[
        token_network_registry_address].tokennetworkaddresses_to_tokennetworks[
            token_network_address] = TokenNetworkState(
                address=token_network_address,
                token_address=token_address,
                network_graph=TokenNetworkGraphState(token_network_address),
            )
    assert empty(
        detect_balance_proof_change(
            empty_chain, chain_with_token_network_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(
            chain_with_registry_no_bp,
            chain_with_token_network_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(
            chain_with_token_network_no_bp,
            deepcopy(chain_with_token_network_no_bp))), MSG_NO_CHANGE

    partner_address = make_address()
    canonical_identifier = make_canonical_identifier()
    channel_no_bp = NettingChannelState(
        canonical_identifier=canonical_identifier,
        token_address=token_address,
        token_network_registry_address=token_network_registry_address,
        reveal_timeout=1,
        settle_timeout=2,
        our_state=NettingChannelEndState(address=our_address,
                                         contract_balance=1),
        partner_state=NettingChannelEndState(address=partner_address,
                                             contract_balance=0),
        open_transaction=TransactionExecutionStatus(result="success"),
        settle_transaction=None,
        update_transaction=None,
        close_transaction=None,
        fee_schedule=FeeScheduleState(),
    )

    chain_with_channel_no_bp = deepcopy(chain_with_token_network_no_bp)
    chain_with_token_network_no_bp.identifiers_to_tokennetworkregistries[
        token_network_registry_address].tokennetworkaddresses_to_tokennetworks[
            token_network_address].channelidentifiers_to_channels[
                canonical_identifier.channel_identifier] = channel_no_bp

    assert empty(
        detect_balance_proof_change(empty_chain,
                                    chain_with_channel_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(chain_with_registry_no_bp,
                                    chain_with_channel_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(chain_with_token_network_no_bp,
                                    chain_with_channel_no_bp)), MSG_NO_CHANGE
    assert empty(
        detect_balance_proof_change(
            chain_with_channel_no_bp,
            deepcopy(chain_with_channel_no_bp))), MSG_NO_CHANGE

    channel_with_sent_bp = deepcopy(channel_no_bp)
    channel_with_sent_bp.our_state.balance_proof = create(
        BalanceProofUnsignedState)

    chain_with_sent_bp = deepcopy(chain_with_token_network_no_bp)
    chain_with_sent_bp.identifiers_to_tokennetworkregistries[
        token_network_registry_address].tokennetworkaddresses_to_tokennetworks[
            token_network_address].channelidentifiers_to_channels[
                canonical_identifier.channel_identifier] = channel_with_sent_bp

    assert not empty(
        detect_balance_proof_change(
            empty_chain,
            chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_registry_no_bp,
            chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_token_network_no_bp,
            chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_channel_no_bp,
            chain_with_sent_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert empty(
        detect_balance_proof_change(
            chain_with_sent_bp, deepcopy(chain_with_sent_bp))), MSG_NO_CHANGE

    channel_with_received_bp = deepcopy(channel_no_bp)
    channel_with_received_bp.partner_state.balance_proof = create(
        BalanceProofUnsignedState)

    chain_with_received_bp = deepcopy(chain_with_token_network_no_bp)
    chain_with_received_bp.identifiers_to_tokennetworkregistries[
        token_network_registry_address].tokennetworkaddresses_to_tokennetworks[
            token_network_address].channelidentifiers_to_channels[
                canonical_identifier.channel_identifier] = channel_with_sent_bp

    # asserting with `channel_with_received_bp` and `channel_with_sent_bp`
    # doesn't make sense, because one of the balance proofs would have to
    # disappear (which is a bug)
    assert not empty(
        detect_balance_proof_change(
            empty_chain,
            chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_registry_no_bp,
            chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_token_network_no_bp,
            chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(
            chain_with_channel_no_bp,
            chain_with_received_bp)), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert empty(
        detect_balance_proof_change(
            chain_with_received_bp,
            deepcopy(chain_with_received_bp))), MSG_NO_CHANGE

    chain_with_sent_and_received_bp = deepcopy(chain_with_token_network_no_bp)
    ta_to_tn = chain_with_sent_and_received_bp.identifiers_to_tokennetworkregistries
    channel_with_sent_and_recived_bp = (
        ta_to_tn[token_network_registry_address].
        tokennetworkaddresses_to_tokennetworks[token_network_address].
        channelidentifiers_to_channels[canonical_identifier.channel_identifier]
    )
    channel_with_sent_and_recived_bp.partner_state.balance_proof = deepcopy(
        channel_with_received_bp.partner_state.balance_proof)
    channel_with_sent_and_recived_bp.our_state.balance_proof = deepcopy(
        channel_with_received_bp.our_state.balance_proof)

    assert not empty(
        detect_balance_proof_change(empty_chain,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(chain_with_registry_no_bp,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(chain_with_token_network_no_bp,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(chain_with_channel_no_bp,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(chain_with_received_bp,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert not empty(
        detect_balance_proof_change(chain_with_sent_bp,
                                    chain_with_sent_and_received_bp)
    ), MSG_BALANCE_PROOF_SHOULD_BE_DETECTED
    assert empty(
        detect_balance_proof_change(
            chain_with_sent_and_received_bp,
            deepcopy(chain_with_sent_and_received_bp))), MSG_NO_CHANGE
示例#31
0
def test_detect_balance_proof_change():
    prng = random.Random()
    block_hash = factories.make_block_hash()
    old = ChainState(
        pseudo_random_generator=prng,
        block_number=1,
        block_hash=block_hash,
        our_address=2,
        chain_id=3,
    )
    new = ChainState(
        pseudo_random_generator=prng,
        block_number=1,
        block_hash=block_hash,
        our_address=2,
        chain_id=3,
    )

    def diff():
        return list(detect_balance_proof_change(old, new))

    assert len(diff()) == 0

    payment_network = PaymentNetworkState(b'x', [])
    payment_network_copy = deepcopy(payment_network)
    new.identifiers_to_paymentnetworks['a'] = payment_network
    assert len(diff()) == 0

    token_network = TokenNetworkState(b'a', b'a')
    token_network_copy = deepcopy(token_network)
    payment_network.tokenidentifiers_to_tokennetworks['a'] = token_network
    assert len(diff()) == 0

    channel = NettingChannelState(
        1,
        0,
        b'a',
        1,
        1,
        1,
        2,
        None,
        None,
        TransactionExecutionStatus(result='success'),
    )
    channel_copy = deepcopy(channel)
    token_network.channelidentifiers_to_channels['a'] = channel
    partner_state = NettingChannelEndState(b'a', 0)
    partner_state_copy = deepcopy(partner_state)
    channel.partner_state = partner_state
    assert len(diff()) == 0

    balance_proof = object()
    partner_state.balance_proof = balance_proof
    assert len(diff()) == 1

    old.identifiers_to_paymentnetworks['a'] = payment_network_copy
    assert len(diff()) == 1

    payment_network_copy.tokenidentifiers_to_tokennetworks[
        'a'] = token_network_copy
    assert len(diff()) == 1

    token_network_copy.channelidentifiers_to_channels['a'] = channel_copy
    channel_copy.partner_state = partner_state_copy
    assert len(diff()) == 1

    channel_copy.partner_state.balance_proof = balance_proof
    assert len(diff()) == 0

    channel_copy.partner_state.balance_proof = object()
    assert len(diff()) == 1

    assert diff() == [balance_proof]