コード例 #1
0
def test_compute_layers_duplicated():
    hash_0 = sha3(b'x')
    hash_1 = sha3(b'y')

    with pytest.raises(ValueError):
        compute_layers([hash_0, hash_0])

    with pytest.raises(ValueError):
        compute_layers([hash_0, hash_1, hash_0])
コード例 #2
0
def test_compute_layers_duplicated():
    hash_0 = sha3(b'x')
    hash_1 = sha3(b'y')

    with pytest.raises(ValueError):
        compute_layers([hash_0, hash_0])

    with pytest.raises(ValueError):
        compute_layers([hash_0, hash_1, hash_0])
コード例 #3
0
def test_channelstate_get_unlock_proof():
    number_of_transfers = 100
    lock_amounts = cycle([1, 3, 5, 7, 11])
    lock_secrets = [
        make_secret(i)
        for i in range(number_of_transfers)
    ]

    block_number = 1000
    locked_amount = 0
    settle_timeout = 8
    merkletree_leaves = []
    locked_locks = {}
    unlocked_locks = {}

    for lock_amount, lock_secret in zip(lock_amounts, lock_secrets):
        block_number += 1
        locked_amount += lock_amount

        lock_expiration = block_number + settle_timeout
        lock_secrethash = sha3(lock_secret)
        lock = HashTimeLockState(
            lock_amount,
            lock_expiration,
            lock_secrethash,
        )

        merkletree_leaves.append(lock.lockhash)
        if random.randint(0, 1) == 0:
            locked_locks[lock_secrethash] = lock
        else:
            unlocked_locks[lock_secrethash] = UnlockPartialProofState(lock, lock_secret)

    end_state = NettingChannelEndState(HOP1, 300)
    end_state.secrethashes_to_lockedlocks = locked_locks
    end_state.secrethashes_to_unlockedlocks = unlocked_locks
    end_state.merkletree = MerkleTreeState(compute_layers(merkletree_leaves))

    unlock_proof = channel.get_batch_unlock(end_state)
    assert len(unlock_proof) == len(end_state.merkletree.layers[LEAVES])
    leaves_packed = b''.join(lock.encoded for lock in unlock_proof)

    recomputed_merkle_tree = MerkleTreeState(compute_layers(
        merkle_leaves_from_packed_data(leaves_packed),
    ))
    assert len(recomputed_merkle_tree.layers[LEAVES]) == len(end_state.merkletree.layers[LEAVES])

    computed_merkleroot = merkleroot(recomputed_merkle_tree)
    assert merkleroot(end_state.merkletree) == computed_merkleroot
コード例 #4
0
def test_many(tree_up_to=10):
    for number_of_leaves in range(1, tree_up_to):  # skipping the empty tree

        leaves = [sha3(str(value)) for value in range(number_of_leaves)]

        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
        root = merkleroot(tree)

        for value in leaves:
            proof = compute_merkleproof_for(tree, value)
            assert validate_proof(proof, root, value)

        reversed_tree = MerkleTreeState(compute_layers(reversed(leaves)))
        assert root == merkleroot(reversed_tree)
コード例 #5
0
def test_merkle_proof_missing_byte(tree, tester_chain,
                                   tester_nettingchannel_library_address):
    """ computeMerkleRoot must fail if the proof is missing a byte. """

    auxiliary = deploy_auxiliary_tester(tester_chain,
                                        tester_nettingchannel_library_address)

    hashes = [sha3(element) for element in tree]
    layers = compute_layers(hashes)
    merkletree = MerkleTreeState(layers)

    element = hashes[-1]
    proof = compute_merkleproof_for(merkletree, element)

    # for each element of the proof, remove a byte from the start and the end and test it
    for element_to_tamper in range(len(proof)):
        tampered_proof = list(proof)
        tampered_proof[element_to_tamper] = tampered_proof[
            element_to_tamper][:-1]

        with pytest.raises(TransactionFailed):
            auxiliary.computeMerkleRoot(
                element,
                b''.join(tampered_proof),
            )

        tampered_proof = list(proof)
        tampered_proof[element_to_tamper] = tampered_proof[element_to_tamper][
            1:]

        with pytest.raises(TransactionFailed):
            auxiliary.computeMerkleRoot(
                element,
                b''.join(tampered_proof),
            )
コード例 #6
0
def deserialize_merkletree_layers(data: typing.List[str]):
    elements = map_list(deserialize_bytes, data)
    if len(elements) == 0:
        from raiden.transfer.state import make_empty_merkle_tree
        return make_empty_merkle_tree().layers

    return compute_layers(elements)
def test_merkle_proof_missing_byte(
        tree,
        tester_chain,
        tester_nettingchannel_library_address):
    """ computeMerkleRoot must fail if the proof is missing a byte. """

    auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address)

    hashes = [sha3(element) for element in tree]
    layers = compute_layers(hashes)
    merkletree = MerkleTreeState(layers)

    element = hashes[-1]
    proof = compute_merkleproof_for(merkletree, element)

    # for each element of the proof, remove a byte from the start and the end and test it
    for element_to_tamper in range(len(proof)):
        tampered_proof = list(proof)
        tampered_proof[element_to_tamper] = tampered_proof[element_to_tamper][:-1]

        with pytest.raises(TransactionFailed):
            auxiliary.computeMerkleRoot(
                element,
                b''.join(tampered_proof),
            )

        tampered_proof = list(proof)
        tampered_proof[element_to_tamper] = tampered_proof[element_to_tamper][1:]

        with pytest.raises(TransactionFailed):
            auxiliary.computeMerkleRoot(
                element,
                b''.join(tampered_proof),
            )
コード例 #8
0
def test_compute_layers_single_entry():
    hash_0 = sha3(b'x')
    layers = compute_layers([hash_0])
    assert layers[MERKLEROOT][0] == hash_0

    tree = MerkleTreeState(layers)
    assert merkleroot(tree) == hash_0
コード例 #9
0
def test_three():
    hash_0 = b'a' * 32
    hash_1 = b'b' * 32
    hash_2 = b'c' * 32

    leaves = [hash_0, hash_1, hash_2]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)

    hash_01 = (
        b'me\xef\x9c\xa9=5\x16\xa4\xd3\x8a\xb7\xd9\x89\xc2\xb5\x00'
        b'\xe2\xfc\x89\xcc\xdc\xf8x\xf9\xc4m\xaa\xf6\xad\r['
    )
    assert sha3(hash_0 + hash_1) == hash_01
    calculated_root = sha3(hash_2 + hash_01)

    proof0 = compute_merkleproof_for(tree, hash_0)
    proof1 = compute_merkleproof_for(tree, hash_1)
    proof2 = compute_merkleproof_for(tree, hash_2)

    assert proof0 == [hash_1, hash_2]
    assert root == calculated_root
    assert validate_proof(proof0, root, hash_0)

    assert proof1 == [hash_0, hash_2]
    assert root == calculated_root
    assert validate_proof(proof1, root, hash_1)

    # with an odd number of values, the last value wont appear by itself in the
    # proof since it isn't hashed with another value
    assert proof2 == [sha3(hash_0 + hash_1)]
    assert root == calculated_root
    assert validate_proof(proof2, root, hash_2)
コード例 #10
0
def test_three():
    hash_0 = b'a' * 32
    hash_1 = b'b' * 32
    hash_2 = b'c' * 32

    leaves = [hash_0, hash_1, hash_2]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)

    hash_01 = (b'me\xef\x9c\xa9=5\x16\xa4\xd3\x8a\xb7\xd9\x89\xc2\xb5\x00'
               b'\xe2\xfc\x89\xcc\xdc\xf8x\xf9\xc4m\xaa\xf6\xad\r[')
    assert sha3(hash_0 + hash_1) == hash_01
    calculated_root = sha3(hash_2 + hash_01)

    proof0 = compute_merkleproof_for(tree, hash_0)
    proof1 = compute_merkleproof_for(tree, hash_1)
    proof2 = compute_merkleproof_for(tree, hash_2)

    assert proof0 == [hash_1, hash_2]
    assert root == calculated_root
    assert validate_proof(proof0, root, hash_0)

    assert proof1 == [hash_0, hash_2]
    assert root == calculated_root
    assert validate_proof(proof1, root, hash_1)

    # with an odd number of values, the last value wont appear by itself in the
    # proof since it isn't hashed with another value
    assert proof2 == [sha3(hash_0 + hash_1)]
    assert root == calculated_root
    assert validate_proof(proof2, root, hash_2)
コード例 #11
0
def test_merkle_proof_one_lock(tester_chain,
                               tester_nettingchannel_library_address):
    """ computeMerkleRoot and the python implementation must compute the same
    value for a merkle tree with a single lock."""

    auxiliary = deploy_auxiliary_tester(tester_chain,
                                        tester_nettingchannel_library_address)

    amount = 10
    expiration = 77
    secret = sha3(b'test_merkle_proof_one_lock')
    secrethash = sha3(secret)
    lock = Lock(amount, expiration, secrethash)

    layers = compute_layers([lock.lockhash])
    merkletree = MerkleTreeState(layers)

    proof = compute_merkleproof_for(merkletree, lock.lockhash)
    assert len(proof) == 0, 'with only one element the proof is empty'

    smart_contact_root = auxiliary.computeMerkleRoot(
        lock.as_bytes,
        b''.join(proof),
    )

    assert smart_contact_root == merkleroot(merkletree)
コード例 #12
0
def test_compute_layers_single_entry():
    hash_0 = sha3(b'x')
    layers = compute_layers([hash_0])
    assert layers[MERKLEROOT][0] == hash_0

    tree = MerkleTreeState(layers)
    assert merkleroot(tree) == hash_0
コード例 #13
0
def deserialize_merkletree_layers(data: List[str]) -> List[List[Keccak256]]:
    elements = cast(List[Keccak256], map_list(deserialize_bytes, data))
    if len(elements) == 0:
        from raiden.transfer.state import make_empty_merkle_tree

        return make_empty_merkle_tree().layers

    return compute_layers(elements)
コード例 #14
0
def test_withdraw_fails_with_partial_merkle_proof(tree, tester_channels,
                                                  tester_chain,
                                                  settle_timeout):
    """ withdraw must fail if informed proof is not complete. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]

    current_block = tester_chain.block.number
    expiration = current_block + settle_timeout - 1
    locks = [
        make_lock(
            hashlock=hashlock,
            expiration=expiration,
        ) for hashlock in tree
    ]

    leaves = [sha3(lock.as_bytes) for lock in locks]
    layers = compute_layers(leaves)
    merkle_tree = MerkleTreeState(layers)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2**32))
    direct_transfer = make_direct_transfer(
        nonce=nonce,
        channel=channel0.identifier,
        locksroot=merkleroot(merkle_tree),
        recipient=privatekey_to_address(pkey1))

    address = privatekey_to_address(pkey0)
    sign_key = PrivateKey(pkey0)
    direct_transfer.sign(sign_key, address)

    direct_transfer_hash = sha3(direct_transfer.packed().data[:-65])
    nettingchannel.close(
        direct_transfer.nonce,
        direct_transfer.transferred_amount,
        direct_transfer.locksroot,
        direct_transfer_hash,
        direct_transfer.signature,
        sender=pkey1,
    )

    for lock in locks:
        secret = HASHLOCKS_SECRESTS[lock.hashlock]
        lock_encoded = lock.as_bytes
        merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded))

        # withdraw must fail regardless of which part of the proof is removed
        for hash_ in merkle_proof:
            tampered_proof = list(merkle_proof)
            tampered_proof.remove(hash_)

            with pytest.raises(TransactionFailed):
                nettingchannel.withdraw(
                    lock_encoded,
                    b''.join(tampered_proof),
                    secret,
                    sender=pkey1,
                )
コード例 #15
0
def deserialize_merkletree_layers(data: typing.List[str]):
    elements = map_list(deserialize_bytes, data)
    if len(elements) == 0:
        return [
            [],  # the leaves are empty
            [bytes(32)],  # the root is the constant 0
        ]

    return compute_layers(elements)
コード例 #16
0
def test_many(tree_up_to=10):
    for number_of_leaves in range(1, tree_up_to):  # skipping the empty tree

        leaves = [
            sha3(str(value).encode())
            for value in range(number_of_leaves)
        ]

        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
        root = merkleroot(tree)

        for value in leaves:
            proof = compute_merkleproof_for(tree, value)
            assert validate_proof(proof, root, value)

        reversed_tree = MerkleTreeState(compute_layers(reversed(leaves)))
        assert root == merkleroot(reversed_tree)
コード例 #17
0
def test_serialization_merkletree_layers():
    hash_0 = b"a" * 32
    hash_1 = b"b" * 32

    leaves = [hash_0, hash_1]
    layers = compute_layers(leaves)

    data = serialization.serialize_merkletree_layers(layers)
    restored = serialization.deserialize_merkletree_layers(data)

    assert layers == restored
コード例 #18
0
def make_receive_transfer_mediated(
        channel_state,
        privkey,
        nonce,
        transferred_amount,
        lock,
        merkletree_leaves=None):

    if not isinstance(lock, HashTimeLockState):
        raise ValueError('lock must be of type HashTimeLockState')

    address = privatekey_to_address(privkey.secret)
    if address not in (channel_state.our_state.address, channel_state.partner_state.address):
        raise ValueError('Private key does not match any of the participants.')

    if merkletree_leaves is None:
        layers = [[lock.lockhash]]
    else:
        assert lock.lockhash in merkletree_leaves
        layers = compute_layers(merkletree_leaves)

    locksroot = layers[MERKLEROOT][0]

    message_identifier = random.randint(0, UINT64_MAX)
    payment_identifier = nonce
    transfer_target = factories.make_address()
    transfer_initiator = factories.make_address()
    mediated_transfer_msg = LockedTransfer(
        message_identifier,
        payment_identifier,
        nonce,
        channel_state.token_address,
        channel_state.identifier,
        transferred_amount,
        channel_state.partner_state.address,
        locksroot,
        lock,
        transfer_target,
        transfer_initiator,
    )
    mediated_transfer_msg.sign(privkey, address)

    balance_proof = balanceproof_from_envelope(mediated_transfer_msg)

    receive_lockedtransfer = LockedTransferSignedState(
        payment_identifier,
        channel_state.token_address,
        balance_proof,
        lock,
        transfer_initiator,
        transfer_target,
    )

    return receive_lockedtransfer
コード例 #19
0
def test_serialization_merkletree_layers():
    hash_0 = b'a' * 32
    hash_1 = b'b' * 32

    leaves = [hash_0, hash_1]
    layers = compute_layers(leaves)

    data = serialization.serialize_merkletree_layers(layers)
    restored = serialization.deserialize_merkletree_layers(data)

    assert layers == restored
コード例 #20
0
    def create(self) -> NettingChannelEndState:
        state = NettingChannelEndState(self.address or make_address(),
                                       self.balance)

        merkletree_leaves = (self.merkletree_leaves
                             or make_merkletree_leaves(self.merkletree_width)
                             or None)
        if merkletree_leaves:
            state.merkletree = MerkleTreeState(
                compute_layers(merkletree_leaves))

        return state
コード例 #21
0
def test_one():
    hash_0 = b'a' * 32

    leaves = [hash_0]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)
    proof = compute_merkleproof_for(tree, hash_0)

    assert proof == []
    assert root == hash_0
    assert validate_proof(proof, root, hash_0) is True
コード例 #22
0
def test_one():
    hash_0 = b'a' * 32

    leaves = [hash_0]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)
    proof = compute_merkleproof_for(tree, hash_0)

    assert proof == []
    assert root == hash_0
    assert validate_proof(proof, root, hash_0) is True
コード例 #23
0
ファイル: transfer.py プロジェクト: sufimerchant/raiden
def make_receive_expired_lock(
    channel_state,
    privkey,
    nonce,
    transferred_amount,
    lock,
    merkletree_leaves=None,
    locked_amount=None,
    chain_id=None,
):

    if not isinstance(lock, HashTimeLockState):
        raise ValueError('lock must be of type HashTimeLockState')

    address = privatekey_to_address(privkey.secret)
    if address not in (channel_state.our_state.address,
                       channel_state.partner_state.address):
        raise ValueError('Private key does not match any of the participants.')

    if merkletree_leaves is None:
        layers = EMPTY_MERKLE_TREE.layers
    else:
        assert lock.lockhash not in merkletree_leaves
        layers = compute_layers(merkletree_leaves)

    locksroot = layers[MERKLEROOT][0]

    chain_id = chain_id or channel_state.chain_id
    lock_expired_msg = LockExpired(
        chain_id=chain_id,
        nonce=nonce,
        message_identifier=random.randint(0, UINT64_MAX),
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
        channel_identifier=channel_state.identifier,
        token_network_address=channel_state.token_network_identifier,
        recipient=channel_state.partner_state.address,
        secrethash=lock.secrethash,
    )
    lock_expired_msg.sign(privkey)

    balance_proof = balanceproof_from_envelope(lock_expired_msg)

    receive_lockedtransfer = ReceiveLockExpired(
        channel_state.partner_state.address,
        balance_proof,
        lock.secrethash,
        random.randint(0, UINT64_MAX),
    )

    return receive_lockedtransfer
コード例 #24
0
ファイル: transfer.py プロジェクト: virrius/lumino
def make_receive_expired_lock(
    channel_state: NettingChannelState,
    privkey: bytes,
    nonce: Nonce,
    transferred_amount: TokenAmount,
    lock: HashTimeLockState,
    merkletree_leaves: List[Keccak256] = None,
    locked_amount: LockedAmount = None,
    chain_id: ChainID = None,
) -> ReceiveLockExpired:

    if not isinstance(lock, HashTimeLockState):
        raise ValueError("lock must be of type HashTimeLockState")

    signer = LocalSigner(privkey)
    address = signer.address
    if address not in (channel_state.our_state.address,
                       channel_state.partner_state.address):
        raise ValueError("Private key does not match any of the participants.")

    if merkletree_leaves is None:
        layers = make_empty_merkle_tree().layers
    else:
        assert lock.lockhash not in merkletree_leaves
        layers = compute_layers(merkletree_leaves)

    locksroot = layers[MERKLEROOT][0]

    chain_id = chain_id or channel_state.chain_id
    lock_expired_msg = LockExpired(
        chain_id=chain_id,
        nonce=nonce,
        message_identifier=random.randint(0, UINT64_MAX),
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
        channel_identifier=channel_state.identifier,
        token_network_address=channel_state.token_network_identifier,
        recipient=channel_state.partner_state.address,
        secrethash=lock.secrethash,
    )
    lock_expired_msg.sign(signer)

    balance_proof = balanceproof_from_envelope(lock_expired_msg)

    receive_lockedtransfer = ReceiveLockExpired(
        balance_proof=balance_proof,
        secrethash=lock.secrethash,
        message_identifier=random.randint(0, UINT64_MAX),
    )

    return receive_lockedtransfer
コード例 #25
0
ファイル: factories.py プロジェクト: hackaugusto/raiden
def _(properties, defaults=None) -> NettingChannelEndState:
    args = _properties_to_kwargs(properties, defaults or NETTING_CHANNEL_END_STATE_DEFAULTS)
    state = NettingChannelEndState(args['address'] or make_address(), args['balance'])

    merkletree_leaves = (
        args['merkletree_leaves'] or
        make_merkletree_leaves(args['merkletree_width']) or
        None
    )
    if merkletree_leaves:
        state.merkletree = MerkleTreeState(compute_layers(merkletree_leaves))

    return state
コード例 #26
0
def _(properties, defaults=None) -> NettingChannelEndState:
    args = _properties_to_kwargs(
        properties, defaults or NETTING_CHANNEL_END_STATE_DEFAULTS)
    state = NettingChannelEndState(args['address'] or make_address(),
                                   args['balance'])

    merkletree_leaves = (args['merkletree_leaves']
                         or make_merkletree_leaves(args['merkletree_width'])
                         or None)
    if merkletree_leaves:
        state.merkletree = MerkleTreeState(compute_layers(merkletree_leaves))

    return state
コード例 #27
0
ファイル: factories.py プロジェクト: offerm/raiden
def _(properties, defaults=None) -> NettingChannelEndState:
    args = _properties_to_kwargs(
        properties, defaults or NettingChannelEndStateProperties.DEFAULTS)
    state = NettingChannelEndState(args["address"] or make_address(),
                                   args["balance"])

    merkletree_leaves = (args["merkletree_leaves"]
                         or make_merkletree_leaves(args["merkletree_width"])
                         or None)
    if merkletree_leaves:
        state.merkletree = MerkleTreeState(compute_layers(merkletree_leaves))

    return state
コード例 #28
0
    def compute_merkleroot_with(self, include):
        """ Compute the resulting merkle root if the lock `include` is added in
        the tree.
        """
        if not self.is_known(include.hashlock):
            leaves = list(self.merkletree.layers[LEAVES])
            leaves.append(sha3(include.as_bytes))

            tree_with = MerkleTreeState(compute_layers(leaves))
            locksroot = merkleroot(tree_with)
        else:
            locksroot = merkleroot(self.merkletree)

        return locksroot
コード例 #29
0
def compute_merkletree_with(
    merkletree: MerkleTreeState,
    lockhash: typing.LockHash,
) -> typing.Optional[MerkleTreeState]:
    """Register the given lockhash with the existing merkle tree."""
    # Use None to inform the caller the lockshash is already known
    result = None

    leaves = merkletree.layers[LEAVES]
    if lockhash not in leaves:
        leaves = list(leaves)
        leaves.append(lockhash)
        result = MerkleTreeState(compute_layers(leaves))

    return result
コード例 #30
0
def compute_merkletree_without(merkletree, lockhash):
    # Use None to inform the caller the lockshash is unknown
    result = None

    leaves = merkletree.layers[LEAVES]
    if lockhash in leaves:
        leaves = list(leaves)
        leaves.remove(lockhash)

        if leaves:
            result = MerkleTreeState(compute_layers(leaves))
        else:
            result = EMPTY_MERKLE_TREE

    return result
コード例 #31
0
ファイル: transfer.py プロジェクト: AlphaX-IBS/raiden
def assert_locked(from_channel, pending_locks):
    """ Assert the locks created from `from_channel`. """
    # a locked transfer is registered in the _partner_ state
    if pending_locks:
        leaves = [sha3(lock.encoded) for lock in pending_locks]
        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
    else:
        tree = EMPTY_MERKLE_TREE

    assert from_channel.our_state.merkletree == tree

    for lock in pending_locks:
        pending = lock.secrethash in from_channel.our_state.secrethashes_to_lockedlocks
        unclaimed = lock.secrethash in from_channel.our_state.secrethashes_to_unlockedlocks
        assert pending or unclaimed
コード例 #32
0
ファイル: transfer.py プロジェクト: nguyenquangminh/raiden
def assert_locked(from_channel, pending_locks):
    """ Assert the locks created from `from_channel`. """
    # a locked transfer is registered in the _partner_ state
    if pending_locks:
        leaves = [sha3(lock.encoded) for lock in pending_locks]
        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
    else:
        tree = EMPTY_MERKLE_TREE

    assert from_channel.our_state.merkletree == tree

    for lock in pending_locks:
        pending = lock.secrethash in from_channel.our_state.secrethashes_to_lockedlocks
        unclaimed = lock.secrethash in from_channel.our_state.secrethashes_to_unlockedlocks
        assert pending or unclaimed
コード例 #33
0
    def compute_merkleroot_without(self, without):
        """ Compute the resulting merkle root if the lock `include` is added in
        the tree.
        """
        if not self.is_known(without.hashlock):
            raise ValueError('unknown lock', lock=without)

        leaves = list(self.merkletree.layers[LEAVES])
        leaves.remove(sha3(without.as_bytes))

        if leaves:
            tree_without = MerkleTreeState(compute_layers(leaves))
            locksroot = merkleroot(tree_without)
        else:
            locksroot = EMPTY_MERKLE_ROOT

        return locksroot
コード例 #34
0
ファイル: transfer.py プロジェクト: virrius/lumino
def assert_locked(from_channel: NettingChannelState,
                  pending_locks: List[HashTimeLockState]) -> None:
    """ Assert the locks created from `from_channel`. """
    # a locked transfer is registered in the _partner_ state
    if pending_locks:
        leaves = [sha3(lock.encoded) for lock in pending_locks]
        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
    else:
        tree = make_empty_merkle_tree()

    assert from_channel.our_state.merkletree == tree

    for lock in pending_locks:
        pending = lock.secrethash in from_channel.our_state.secrethashes_to_lockedlocks
        unclaimed = lock.secrethash in from_channel.our_state.secrethashes_to_unlockedlocks
        assert pending or unclaimed
コード例 #35
0
ファイル: channelState.py プロジェクト: cnrlab341/payGo
    def create_BP(self, w3, cr, initiator, target, secrethash, amount, expiration, s_contract, a_contract, start_time):
        # self.lock.acquire()
        # try:
        #     self.locked_amount[self.i] += amount + s_contract[0]
        # finally:
        #     self.lock.release()
        # print("locked_amount ", self.locked_amount[self.i])

        # uint = 32bytes, address = 20bytes, bytes32 = 32bytes
        leaf = pack_data(['uint256', 'uint256', 'bytes32', 'uint256', 'uint256', 'uint256', 'uint256', 'uint256', 'address'],
                         [amount+s_contract[0], expiration, secrethash, s_contract[0],
                          s_contract[1], a_contract[0][0], a_contract[1][1], start_time, target])
        self.leaves[self.i][cr] = leaf
        temp = []
        for i in list(self.leaves[self.i].values()) :
            temp.append(sha3(i))
        layer = compute_layers(temp)
        tree = MerkleTreeState(layer)
        locksroot = "0x" + merkleroot(tree).hex()
        # print("locksroot ", locksroot)

        self.locksroot[self.i] = locksroot
        self.nonce +=1

        message_data = LockedTransfer_structure(self.nonce, self.chain_id, cr, expiration, self.token_network.address, self.channel_identifier,
                                                 self.addrs[1-self.i], target, initiator, locksroot, secrethash, self.transferred_amount[self.i],
                                                self.locked_amount[self.i], amount, s_contract[0], s_contract[1], a_contract[0][0], a_contract[1][1], start_time)
        packed_message_data = message_data.pack()
        additional_hash = '0x' + sha3(packed_message_data).hex()
        # print("additional_hash ", additional_hash)

        packed_balance = pack_data(['uint256', 'uint256', 'bytes32'], [self.transferred_amount[self.i], self.locked_amount[self.i], locksroot])
        balance_hash = '0x' + sha3(packed_balance).hex()
        # print("balance_hash ", balance_hash)

        packed_balance_proof = pack_data(['uint256', 'bytes32', 'uint256', 'bytes32'],
                                         [self.channel_identifier, balance_hash, self.nonce, additional_hash])

        hashBP = '0x' + sha3(packed_balance_proof).hex()
        signature = w3.eth.account.signHash(message_hash=hashBP, private_key=self.sk)
        # print("signature", signature)
        BP = balanceProof(message_data, additional_hash, balance_hash, signature['signature'].hex())
        self.BP[self.i] = BP

        return BP
コード例 #36
0
def test_two():
    hash_0 = b'a' * 32
    hash_1 = b'b' * 32

    leaves = [hash_0, hash_1]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)
    proof0 = compute_merkleproof_for(tree, hash_0)
    proof1 = compute_merkleproof_for(tree, hash_1)

    assert proof0 == [hash_1]
    assert root == sha3(hash_0 + hash_1)
    assert validate_proof(proof0, root, hash_0)

    assert proof1 == [hash_0]
    assert root == sha3(hash_0 + hash_1)
    assert validate_proof(proof1, root, hash_1)
コード例 #37
0
def test_two():
    hash_0 = b'a' * 32
    hash_1 = b'b' * 32

    leaves = [hash_0, hash_1]
    layers = compute_layers(leaves)
    tree = MerkleTreeState(layers)
    root = merkleroot(tree)
    proof0 = compute_merkleproof_for(tree, hash_0)
    proof1 = compute_merkleproof_for(tree, hash_1)

    assert proof0 == [hash_1]
    assert root == sha3(hash_0 + hash_1)
    assert validate_proof(proof0, root, hash_0)

    assert proof1 == [hash_0]
    assert root == sha3(hash_0 + hash_1)
    assert validate_proof(proof1, root, hash_1)
コード例 #38
0
    def register_locked_transfer(self, locked_transfer):
        """ Register the latest known transfer.

        The sender needs to use this method before sending a locked transfer,
        otherwise the calculate locksroot of the transfer message will be
        invalid and the transfer will be rejected by the partner. Since the
        sender wants the transfer to be accepted by the receiver otherwise the
        transfer won't proceed and the sender won't receive their fee.

        The receiver needs to use this method to update the container with a
        _valid_ transfer, otherwise the locksroot will not contain the pending
        transfer. The receiver needs to ensure that the merkle root has the
        hashlock included, otherwise it won't be able to claim it.

        Args:
            transfer (LockedTransfer): The transfer to be added.

        Raises:
            InvalidLocksRoot: If the merkleroot of `locked_transfer` does not
            match with the expected value.

            ValueError: If the transfer contains a lock that was registered
            previously.
        """
        balance_proof = locked_transfer.to_balanceproof()
        lock = locked_transfer.lock
        lockhashed = sha3(lock.as_bytes)

        if self.is_known(lock.hashlock):
            raise ValueError('hashlock is already registered')

        leaves = list(self.merkletree.layers[LEAVES])
        leaves.append(lockhashed)

        newtree = MerkleTreeState(compute_layers(leaves))
        locksroot = merkleroot(newtree)

        if balance_proof.locksroot != locksroot:
            raise InvalidLocksRoot(locksroot, balance_proof.locksroot)

        self.hashlocks_to_pendinglocks[lock.hashlock] = PendingLock(
            lock, lockhashed)
        self.balance_proof = balance_proof
        self.merkletree = newtree
コード例 #39
0
ファイル: transfer.py プロジェクト: devilishwtr/raiden
def assert_locked(from_channel, pending_locks):
    """ Assert the locks created from `from_channel`. """
    # a locked transfer is registered in the _partner_ state
    if pending_locks:
        leaves = [sha3(lock.as_bytes) for lock in pending_locks]
        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
        root = merkleroot(tree)
    else:
        root = EMPTY_MERKLE_ROOT

    assert len(
        from_channel.our_state.hashlocks_to_pendinglocks) == len(pending_locks)
    assert merkleroot(from_channel.our_state.merkletree) == root
    assert from_channel.our_state.amount_locked == sum(
        lock.amount for lock in pending_locks)
    assert from_channel.locked == sum(lock.amount for lock in pending_locks)

    for lock in pending_locks:
        assert lock.hashlock in from_channel.our_state.hashlocks_to_pendinglocks
コード例 #40
0
def assert_locked(from_channel, pending_locks):
    """ Assert the locks created from `from_channel`. """
    # a locked transfer is registered in the _partner_ state
    if pending_locks:
        leaves = [sha3(lock.as_bytes) for lock in pending_locks]
        layers = compute_layers(leaves)
        tree = MerkleTreeState(layers)
        root = merkleroot(tree)
    else:
        root = EMPTY_MERKLE_ROOT

    assert len(from_channel.our_state.hashlocks_to_pendinglocks) == len(
        pending_locks
    )
    assert merkleroot(from_channel.our_state.merkletree) == root
    assert from_channel.our_state.amount_locked == sum(lock.amount for lock in pending_locks)
    assert from_channel.locked == sum(lock.amount for lock in pending_locks)

    for lock in pending_locks:
        assert lock.hashlock in from_channel.our_state.hashlocks_to_pendinglocks
コード例 #41
0
def test_merkle_proof(tree, tester_chain,
                      tester_nettingchannel_library_address):
    """ computeMerkleRoot and the python implementation must compute the same value. """

    auxiliary = deploy_auxiliary_tester(tester_chain,
                                        tester_nettingchannel_library_address)

    hashes = [sha3(element) for element in tree]
    layers = compute_layers(hashes)
    merkletree = MerkleTreeState(layers)

    for element in tree:
        proof = compute_merkleproof_for(merkletree, sha3(element))

        smart_contact_root = auxiliary.computeMerkleRoot(
            element,
            b''.join(proof),
        )

        assert smart_contact_root == merkleroot(merkletree)
def test_merkle_proof(
        tree,
        tester_chain,
        tester_nettingchannel_library_address):
    """ computeMerkleRoot and the python implementation must compute the same value. """

    auxiliary = deploy_auxiliary_tester(tester_chain, tester_nettingchannel_library_address)

    hashes = [sha3(element) for element in tree]
    layers = compute_layers(hashes)
    merkletree = MerkleTreeState(layers)

    for element in tree:
        proof = compute_merkleproof_for(merkletree, sha3(element))

        smart_contact_root = auxiliary.computeMerkleRoot(
            element,
            b''.join(proof),
        )

        assert smart_contact_root == merkleroot(merkletree)
コード例 #43
0
def test_receiver_cannot_spend_locked_amount():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    privkey2, address2 = make_privkey_address()

    balance1 = 33
    balance2 = 11

    reveal_timeout = 7
    settle_timeout = 21
    block_number = 7

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount1 = balance2
    expiration = block_number + settle_timeout
    receive_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount1,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    receive_mediated_transfer0.sign(privkey2, address2)

    test_channel.register_transfer(
        block_number,
        receive_mediated_transfer0,
    )

    # trying to send one unit of the locked token
    amount2 = balance1 + 1
    lock2 = Lock(
        amount=amount2,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    layers = compute_layers([sha3(lock2.as_bytes)])
    tree2 = MerkleTreeState(layers)
    locksroot2 = merkleroot(tree2)

    send_mediated_transfer0 = MediatedTransfer(
        identifier=1,
        nonce=1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    send_mediated_transfer0.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            send_mediated_transfer0,
        )
コード例 #44
0
def test_compute_layers_empty():
    with pytest.raises(AssertionError):
        compute_layers([])
コード例 #45
0
def test_withdraw_tampered_lock_amount(
        tree,
        tester_channels,
        tester_chain,
        tester_token,
        settle_timeout):

    """ withdraw must fail if the lock amonut is tampered. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]

    current_block = tester_chain.block.number
    expiration = current_block + settle_timeout - 1
    locks = [
        make_lock(
            hashlock=hashlock,
            expiration=expiration,
        )
        for hashlock in tree
    ]

    leaves = [sha3(lock.as_bytes) for lock in locks]
    layers = compute_layers(leaves)
    merkle_tree = MerkleTreeState(layers)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2 ** 32))
    direct_transfer = make_direct_transfer(
        nonce=nonce,
        channel=channel0.channel_address,
        locksroot=merkleroot(merkle_tree),
        token=tester_token.address,
        recipient=privatekey_to_address(pkey1)
    )

    address = privatekey_to_address(pkey0)
    sign_key = PrivateKey(pkey0)
    direct_transfer.sign(sign_key, address)

    direct_transfer_hash = sha3(direct_transfer.packed().data[:-65])
    nettingchannel.close(
        direct_transfer.nonce,
        direct_transfer.transferred_amount,
        direct_transfer.locksroot,
        direct_transfer_hash,
        direct_transfer.signature,
        sender=pkey1,
    )

    for lock in locks:
        secret = HASHLOCKS_SECRESTS[lock.hashlock]

        lock_encoded = lock.as_bytes
        merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded))

        tampered_lock = make_lock(
            amount=lock.amount * 100,
            hashlock=lock.hashlock,
            expiration=lock.expiration,
        )
        tampered_lock_encoded = sha3(tampered_lock.as_bytes)

        with pytest.raises(TransactionFailed):
            nettingchannel.withdraw(
                tampered_lock_encoded,
                b''.join(merkle_proof),
                secret,
                sender=pkey1,
            )
コード例 #46
0
def test_compute_layers_invalid_length():
    with pytest.raises(HashLengthNot32):
        compute_layers(['not32bytes', 'neither'])

    with pytest.raises(HashLengthNot32):
        compute_layers([''])
コード例 #47
0
def test_sender_cannot_overspend():
    token_address = make_address()
    privkey1, address1 = make_privkey_address()
    address2 = make_address()

    balance1 = 70
    balance2 = 110

    reveal_timeout = 5
    settle_timeout = 15
    block_number = 10

    our_state = ChannelEndState(address1, balance1, None, EMPTY_MERKLE_TREE)
    partner_state = ChannelEndState(address2, balance2, None, EMPTY_MERKLE_TREE)
    external_state = make_external_state()

    test_channel = Channel(
        our_state,
        partner_state,
        external_state,
        token_address,
        reveal_timeout,
        settle_timeout,
    )

    amount = balance1
    expiration = block_number + settle_timeout
    sent_mediated_transfer0 = test_channel.create_mediatedtransfer(
        address1,
        address2,
        fee=0,
        amount=amount,
        identifier=1,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent'),
    )
    sent_mediated_transfer0.sign(privkey1, address1)

    test_channel.register_transfer(
        block_number,
        sent_mediated_transfer0,
    )

    lock2 = Lock(
        amount=amount,
        expiration=expiration,
        hashlock=sha3(b'test_locked_amount_cannot_be_spent2'),
    )
    leaves = [
        sha3(sent_mediated_transfer0.lock.as_bytes),
        sha3(lock2.as_bytes),
    ]
    tree2 = MerkleTreeState(compute_layers(leaves))
    locksroot2 = merkleroot(tree2)

    sent_mediated_transfer1 = MediatedTransfer(
        identifier=2,
        nonce=sent_mediated_transfer0.nonce + 1,
        token=token_address,
        channel=test_channel.channel_address,
        transferred_amount=0,
        recipient=address2,
        locksroot=locksroot2,
        lock=lock2,
        target=address2,
        initiator=address1,
        fee=0,
    )
    sent_mediated_transfer1.sign(privkey1, address1)

    # address1 balance is all locked
    with pytest.raises(InsufficientBalance):
        test_channel.register_transfer(
            block_number,
            sent_mediated_transfer1,
        )
コード例 #48
0
def test_withdraw_tampered_merkle_proof(tree, tester_channels, tester_chain, settle_timeout):
    """ withdraw must fail if the proof is tampered. """
    pkey0, pkey1, nettingchannel, channel0, _ = tester_channels[0]

    current_block = tester_chain.block.number
    expiration = current_block + settle_timeout - 1
    locks = [
        make_lock(
            hashlock=hashlock,
            expiration=expiration,
        )
        for hashlock in tree
    ]

    leaves = [sha3(lock.as_bytes) for lock in locks]
    layers = compute_layers(leaves)
    merkle_tree = MerkleTreeState(layers)

    opened_block = nettingchannel.opened(sender=pkey0)
    nonce = 1 + (opened_block * (2 ** 32))
    direct_transfer = make_direct_transfer(
        nonce=nonce,
        channel=channel0.channel_address,
        locksroot=merkleroot(merkle_tree),
        recipient=privatekey_to_address(pkey1)
    )

    address = privatekey_to_address(pkey0)
    sign_key = PrivateKey(pkey0)
    direct_transfer.sign(sign_key, address)

    direct_transfer_hash = sha3(direct_transfer.packed().data[:-65])
    nettingchannel.close(
        direct_transfer.nonce,
        direct_transfer.transferred_amount,
        direct_transfer.locksroot,
        direct_transfer_hash,
        direct_transfer.signature,
        sender=pkey1,
    )

    for lock in locks:
        secret = HASHLOCKS_SECRESTS[lock.hashlock]

        lock_encoded = lock.as_bytes
        merkle_proof = compute_merkleproof_for(merkle_tree, sha3(lock_encoded))

        # withdraw must fail regardless of which part of the proof is tampered
        for pos, hash_ in enumerate(merkle_proof):
            # changing arbitrary bytes from the proof
            tampered_hash = bytearray(hash_)
            tampered_hash[6], tampered_hash[7] = tampered_hash[7], tampered_hash[6]

            tampered_proof = list(merkle_proof)
            tampered_proof[pos] = tampered_hash

            joiner = b''
            with pytest.raises(TransactionFailed):
                nettingchannel.withdraw(
                    lock_encoded,
                    joiner.join(tampered_proof),
                    secret,
                    sender=pkey1,
                )
コード例 #49
0
    def restore_channel(self, serialized_channel):
        token_address = serialized_channel.token_address

        netting_channel = self.chain.netting_channel(
            serialized_channel.channel_address,
        )

        # restoring balances from the blockchain since the serialized
        # value could be falling behind.
        channel_details = netting_channel.detail()

        # our_address is checked by detail
        assert channel_details['partner_address'] == serialized_channel.partner_address

        if serialized_channel.our_leaves:
            our_layers = compute_layers(serialized_channel.our_leaves)
            our_tree = MerkleTreeState(our_layers)
        else:
            our_tree = EMPTY_MERKLE_TREE

        our_state = ChannelEndState(
            channel_details['our_address'],
            channel_details['our_balance'],
            serialized_channel.our_balance_proof,
            our_tree,
        )

        if serialized_channel.partner_leaves:
            partner_layers = compute_layers(serialized_channel.partner_leaves)
            partner_tree = MerkleTreeState(partner_layers)
        else:
            partner_tree = EMPTY_MERKLE_TREE

        partner_state = ChannelEndState(
            channel_details['partner_address'],
            channel_details['partner_balance'],
            serialized_channel.partner_balance_proof,
            partner_tree,
        )

        def register_channel_for_hashlock(channel, hashlock):
            self.register_channel_for_hashlock(
                token_address,
                channel,
                hashlock,
            )

        external_state = ChannelExternalState(
            register_channel_for_hashlock,
            netting_channel,
        )
        details = ChannelDetails(
            serialized_channel.channel_address,
            our_state,
            partner_state,
            external_state,
            serialized_channel.reveal_timeout,
            channel_details['settle_timeout'],
        )

        graph = self.token_to_channelgraph[token_address]
        graph.add_channel(details)
        channel = graph.address_to_channel.get(
            serialized_channel.channel_address,
        )

        channel.our_state.balance_proof = serialized_channel.our_balance_proof
        channel.partner_state.balance_proof = serialized_channel.partner_balance_proof