def _(properties, defaults=None) -> LockedTransferSignedState: defaults = defaults or LOCKED_TRANSFER_SIGNED_STATE_DEFAULTS params = _properties_to_dict(properties, defaults) transfer_params = _properties_to_dict(params.pop('transfer'), defaults.transfer) balance_proof_params = _properties_to_dict( transfer_params.pop('balance_proof'), defaults.transfer.balance_proof, ) lock = Lock( amount=transfer_params.pop('amount'), expiration=transfer_params.pop('expiration'), secrethash=sha3(transfer_params.pop('secret')), ) pkey = params.pop('pkey') sender = params.pop('sender') params.update(transfer_params) params.update(balance_proof_params) params['token_network_address'] = params.pop('token_network_identifier') if params['locksroot'] == EMPTY_MERKLE_ROOT: params['locksroot'] = lock.lockhash locked_transfer = LockedTransfer(lock=lock, **params) locked_transfer.sign(pkey) assert locked_transfer.sender == sender return lockedtransfersigned_from_message(locked_transfer)
def make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=1, message_identifier=None, nonce=1, transferred_amount=0, locked_amount=None, locksroot=EMPTY_MERKLE_ROOT, recipient=UNIT_TRANSFER_TARGET, channel_identifier=UNIT_CHANNEL_ID, token=UNIT_TOKEN_ADDRESS, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, ): if message_identifier is None: message_identifier = random.randint(0, UINT64_MAX) secrethash = sha3(secret) lock = Lock( amount, expiration, secrethash, ) if locksroot == EMPTY_MERKLE_ROOT: locksroot = sha3(lock.as_bytes) if locked_amount is None: locked_amount = amount else: assert locked_amount >= amount transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=nonce, token_network_address=UNIT_TOKEN_NETWORK_ADDRESS, token=token, channel_identifier=channel_identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=recipient, locksroot=locksroot, lock=lock, target=target, initiator=initiator, ) transfer.sign(pkey) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
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
def make_signed_transfer( amount, initiator, target, expiration, secret, payment_identifier=1, message_identifier=None, nonce=1, transferred_amount=0, locked_amount=None, recipient=UNIT_TRANSFER_TARGET, channel_identifier=UNIT_CHANNEL_ADDRESS, token=UNIT_TOKEN_ADDRESS, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER, ): if message_identifier is None: message_identifier = random.randint(0, UINT64_MAX) secrethash = sha3(secret) lock = Lock( amount, expiration, secrethash, ) if locked_amount is None: locked_amount = amount else: assert locked_amount >= amount transfer = LockedTransfer( message_identifier, payment_identifier, nonce, UNIT_REGISTRY_IDENTIFIER, token, channel_identifier, transferred_amount, locked_amount, recipient, lock.lockhash, lock, target, initiator, ) transfer.sign(pkey) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
def test_locked_transfer(iterations=ITERATIONS): amount = 1 expiration = 1 hashlock = sha3(ADDRESS) lock = Lock(amount, expiration, hashlock) nonce = 1 asset = ADDRESS balance = 1 recipient = ADDRESS locksroot = sha3(ADDRESS) msg = LockedTransfer(nonce, asset, balance, recipient, locksroot, lock) msg.sign(PRIVKEY) run_timeit('LockedTransfer', msg, iterations=iterations)
def make_signed_transfer( amount, initiator, target, expiration, secret, identifier=1, nonce=1, transferred_amount=0, recipient=UNIT_TRANSFER_TARGET, channel_identifier=UNIT_CHANNEL_ADDRESS, token=UNIT_TOKEN_ADDRESS, pkey=UNIT_TRANSFER_PKEY, sender=UNIT_TRANSFER_SENDER ): secrethash = sha3(secret) lock = Lock( amount, expiration, secrethash, ) transfer = LockedTransfer( identifier, nonce, token, channel_identifier, transferred_amount, recipient, lock.lockhash, lock, target, initiator, ) transfer.sign(pkey, sender) return lockedtransfersigned_from_message(transfer)
def test_withdraw_at_settlement_block( tester_registry_address, deposit, settle_timeout, tester_nettingcontracts, tester_chain, tester_token, ): """ It must be possible to unlock a lock up to and including the settlment block. """ pkey0, pkey1, nettingchannel = tester_nettingcontracts[0] address0 = privatekey_to_address(pkey0) address1 = privatekey_to_address(pkey1) initial_balance0 = tester_token.balanceOf(address0, sender=pkey0) initial_balance1 = tester_token.balanceOf(address1, sender=pkey0) lock_amount = 31 lock_expiration = tester_chain.block.number + settle_timeout secret = b'settlementsettlementsettlementse' secrethash = sha3(secret) lock0 = Lock( amount=lock_amount, expiration=lock_expiration, secrethash=secrethash, ) lock0_bytes = bytes(lock0.as_bytes) lock0_hash = sha3(lock0_bytes) opened_block = nettingchannel.opened(sender=pkey0) nonce = 1 + (opened_block * (2 ** 32)) message_identifier = random.randint(0, UINT64_MAX) mediated0 = LockedTransfer( message_identifier=message_identifier, payment_identifier=1, nonce=nonce, registry_address=tester_registry_address, token=tester_token.address, channel=to_canonical_address(nettingchannel.address), transferred_amount=0, locked_amount=lock_amount, recipient=address1, locksroot=lock0_hash, lock=lock0, target=address1, initiator=address0, fee=0, ) sign_key0 = PrivateKey(pkey0) mediated0.sign(sign_key0, address0) mediated0_hash = sha3(mediated0.packed().data[:-65]) nettingchannel.close( mediated0.nonce, mediated0.transferred_amount, mediated0.locksroot, mediated0_hash, mediated0.signature, sender=pkey1, ) block_until_settlement_end = lock_expiration - tester_chain.block.number tester_chain.mine(number_of_blocks=block_until_settlement_end) assert lock_expiration == tester_chain.block.number nettingchannel.withdraw( lock0_bytes, b'', # the lock itself it the root, the proof is empty secret, sender=pkey1, ) tester_chain.mine(number_of_blocks=1) nettingchannel.settle(sender=pkey0) balance0 = initial_balance0 + deposit - lock0.amount balance1 = initial_balance1 + deposit + lock0.amount assert tester_token.balanceOf(address0, sender=pkey0) == balance0 assert tester_token.balanceOf(address1, sender=pkey0) == balance1 assert tester_token.balanceOf(nettingchannel.address, sender=pkey0) == 0
def make_signed_transfer( amount: typing.TokenAmount = EMPTY, initiator: typing.InitiatorAddress = EMPTY, target: typing.TargetAddress = EMPTY, expiration: typing.BlockExpiration = EMPTY, secret: typing.Secret = EMPTY, payment_identifier: typing.PaymentID = EMPTY, message_identifier: typing.MessageID = EMPTY, nonce: typing.Nonce = EMPTY, transferred_amount: typing.TokenAmount = EMPTY, locked_amount: typing.TokenAmount = EMPTY, locksroot: typing.Locksroot = EMPTY, recipient: typing.Address = EMPTY, channel_identifier: typing.ChannelID = EMPTY, token_network_address: typing.TokenNetworkID = EMPTY, token: typing.TargetAddress = EMPTY, pkey: bytes = EMPTY, sender: typing.Address = EMPTY, ) -> LockedTransferSignedState: amount = if_empty(amount, UNIT_TRANSFER_AMOUNT) initiator = if_empty(initiator, make_address()) target = if_empty(target, make_address()) expiration = if_empty(expiration, UNIT_REVEAL_TIMEOUT) secret = if_empty(secret, make_secret()) payment_identifier = if_empty(payment_identifier, 1) message_identifier = if_empty(message_identifier, make_message_identifier()) nonce = if_empty(nonce, 1) transferred_amount = if_empty(transferred_amount, 0) locked_amount = if_empty(locked_amount, amount) locksroot = if_empty(locksroot, EMPTY_MERKLE_ROOT) recipient = if_empty(recipient, UNIT_TRANSFER_TARGET) channel_identifier = if_empty(channel_identifier, UNIT_CHANNEL_ID) token_network_address = if_empty(token_network_address, UNIT_TOKEN_NETWORK_ADDRESS) token = if_empty(token, UNIT_TOKEN_ADDRESS) pkey = if_empty(pkey, UNIT_TRANSFER_PKEY) signer = LocalSigner(pkey) sender = if_empty(sender, UNIT_TRANSFER_SENDER) assert locked_amount >= amount secrethash = sha3(secret) lock = Lock( amount=amount, expiration=expiration, secrethash=secrethash, ) if locksroot == EMPTY_MERKLE_ROOT: locksroot = sha3(lock.as_bytes) transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=nonce, token_network_address=token_network_address, token=token, channel_identifier=channel_identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=recipient, locksroot=locksroot, lock=lock, target=target, initiator=initiator, ) transfer.sign(signer) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
def make_receive_transfer_mediated( channel_state, privkey, nonce, transferred_amount, lock, merkletree_leaves=None, token_network_address=UNIT_REGISTRY_IDENTIFIER, locked_amount=None, chain_id=UNIT_CHAIN_ID, ): 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) if locked_amount is None: locked_amount = lock.amount assert locked_amount >= lock.amount locksroot = layers[MERKLEROOT][0] payment_identifier = nonce transfer_target = make_address() transfer_initiator = make_address() mediated_transfer_msg = LockedTransfer( chain_id=chain_id, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, nonce=nonce, token_network_address=token_network_address, token=channel_state.token_address, channel_identifier=channel_state.identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=channel_state.partner_state.address, locksroot=locksroot, lock=lock, target=transfer_target, initiator=transfer_initiator, ) mediated_transfer_msg.sign(privkey) balance_proof = balanceproof_from_envelope(mediated_transfer_msg) receive_lockedtransfer = LockedTransferSignedState( random.randint(0, UINT64_MAX), payment_identifier, channel_state.token_address, balance_proof, lock, transfer_initiator, transfer_target, ) return receive_lockedtransfer
def make_signed_transfer( amount: typing.TokenAmount = EMPTY, initiator: typing.InitiatorAddress = EMPTY, target: typing.TargetAddress = EMPTY, expiration: typing.BlockExpiration = EMPTY, secret: typing.Secret = EMPTY, payment_identifier: typing.PaymentID = EMPTY, message_identifier: typing.MessageID = EMPTY, nonce: typing.Nonce = EMPTY, transferred_amount: typing.TokenAmount = EMPTY, locked_amount: typing.TokenAmount = EMPTY, locksroot: typing.Locksroot = EMPTY, recipient: typing.Address = EMPTY, channel_identifier: typing.ChannelID = EMPTY, token_network_address: typing.TokenNetworkID = EMPTY, token: typing.TargetAddress = EMPTY, pkey: PrivateKey = EMPTY, sender: typing.Address = EMPTY, ) -> LockedTransferSignedState: amount = if_empty(amount, UNIT_TRANSFER_AMOUNT) initiator = if_empty(initiator, make_address()) target = if_empty(target, make_address()) expiration = if_empty(expiration, UNIT_REVEAL_TIMEOUT) secret = if_empty(secret, make_secret()) payment_identifier = if_empty(payment_identifier, 1) message_identifier = if_empty(message_identifier, make_message_identifier()) nonce = if_empty(nonce, 1) transferred_amount = if_empty(transferred_amount, 0) locked_amount = if_empty(locked_amount, amount) locksroot = if_empty(locksroot, EMPTY_MERKLE_ROOT) recipient = if_empty(recipient, UNIT_TRANSFER_TARGET) channel_identifier = if_empty(channel_identifier, UNIT_CHANNEL_ID) token_network_address = if_empty(token_network_address, UNIT_TOKEN_NETWORK_ADDRESS) token = if_empty(token, UNIT_TOKEN_ADDRESS) pkey = if_empty(pkey, UNIT_TRANSFER_PKEY) sender = if_empty(sender, UNIT_TRANSFER_SENDER) assert locked_amount >= amount secrethash = sha3(secret) lock = Lock( amount=amount, expiration=expiration, secrethash=secrethash, ) if locksroot == EMPTY_MERKLE_ROOT: locksroot = sha3(lock.as_bytes) transfer = LockedTransfer( chain_id=UNIT_CHAIN_ID, message_identifier=message_identifier, payment_identifier=payment_identifier, nonce=nonce, token_network_address=token_network_address, token=token, channel_identifier=channel_identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=recipient, locksroot=locksroot, lock=lock, target=target, initiator=initiator, ) transfer.sign(pkey) assert transfer.sender == sender return lockedtransfersigned_from_message(transfer)
def make_receive_transfer_mediated( channel_state: NettingChannelState, privkey: bytes, nonce: Nonce, transferred_amount: TokenAmount, lock: HashTimeLockState, merkletree_leaves: List[Keccak256] = None, locked_amount: Optional[LockedAmount] = None, chain_id: Optional[ChainID] = None, ) -> LockedTransferSignedState: 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 = [[lock.lockhash]] else: assert lock.lockhash in merkletree_leaves layers = compute_layers(merkletree_leaves) if locked_amount is None: locked_amount = lock.amount assert locked_amount >= lock.amount locksroot = layers[MERKLEROOT][0] payment_identifier = nonce payment_hash_invoice = make_payment_hash_invoice() transfer_target = make_address() transfer_initiator = make_address() chain_id = chain_id or channel_state.chain_id mediated_transfer_msg = LockedTransfer( chain_id=chain_id, message_identifier=random.randint(0, UINT64_MAX), payment_identifier=payment_identifier, payment_hash_invoice=payment_hash_invoice, nonce=nonce, token_network_address=channel_state.token_network_identifier, token=channel_state.token_address, channel_identifier=channel_state.identifier, transferred_amount=transferred_amount, locked_amount=locked_amount, recipient=channel_state.partner_state.address, locksroot=locksroot, lock=lock, target=transfer_target, initiator=transfer_initiator, ) mediated_transfer_msg.sign(signer) balance_proof = balanceproof_from_envelope(mediated_transfer_msg) receive_lockedtransfer = LockedTransferSignedState( random.randint(0, UINT64_MAX), payment_identifier, payment_hash_invoice, channel_state.token_address, balance_proof, lock, transfer_initiator, transfer_target, ) return receive_lockedtransfer