def detail_participants(  # pylint: disable=unused-argument
            participant1, participant2, block_identifier, channel_identifier):
        transferred_amount = 1
        locked_amount = 1
        locksroot = make_32bytes()
        balance_hash = hash_balance_data(transferred_amount, locked_amount,
                                         locksroot)
        our_details = ParticipantDetails(
            address=raiden.address,
            deposit=5,
            withdrawn=0,
            is_closer=False,
            balance_hash=balance_hash,
            nonce=1,
            locksroot=locksroot,
            locked_amount=locked_amount,
        )

        transferred_amount = 1
        locked_amount = 1
        # Let's mock here that partner locksroot is 0x0
        balance_hash = hash_balance_data(transferred_amount, locked_amount,
                                         locksroot)
        partner_details = ParticipantDetails(
            address=participant,
            deposit=5,
            withdrawn=0,
            is_closer=True,
            balance_hash=balance_hash,
            nonce=1,
            locksroot=EMPTY_HASH,
            locked_amount=locked_amount,
        )
        return ParticipantsDetails(our_details, partner_details)
    def detail_participants(participant1, participant2, channel_identifier):
        transferred_amount = 1
        locked_amount = 1
        locksroot = make_32bytes()
        balance_hash = hash_balance_data(transferred_amount, locked_amount, locksroot)
        our_details = ParticipantDetails(
            address=raiden.address,
            deposit=5,
            withdrawn=0,
            is_closer=False,
            balance_hash=balance_hash,
            nonce=1,
            locksroot=locksroot,
            locked_amount=locked_amount,
        )

        transferred_amount = 1
        locked_amount = 1
        # Let's mock here that partner locksroot is 0x0
        locksroot = EMPTY_HASH
        balance_hash = hash_balance_data(transferred_amount, locked_amount, locksroot)
        partner_details = ParticipantDetails(
            address=participant,
            deposit=5,
            withdrawn=0,
            is_closer=True,
            balance_hash=balance_hash,
            nonce=1,
            locksroot=locksroot,
            locked_amount=locked_amount,
        )
        return ParticipantsDetails(our_details, partner_details)
    def detail_participants(_participant1, _participant2, _block_identifier,
                            _channel_identifier):
        transferred_amount = TokenAmount(1)
        locked_amount = LockedAmount(1)
        locksroot = make_locksroot()
        balance_hash = hash_balance_data(transferred_amount, locked_amount,
                                         locksroot)
        our_details = ParticipantDetails(
            address=raiden.address,
            deposit=TokenAmount(5),
            withdrawn=WithdrawAmount(0),
            is_closer=False,
            balance_hash=balance_hash,
            nonce=Nonce(1),
            locksroot=locksroot,
            locked_amount=locked_amount,
        )

        transferred_amount = TokenAmount(1)
        locked_amount = LockedAmount(1)
        # Let's mock here that partner locksroot is 0x0
        balance_hash = hash_balance_data(transferred_amount, locked_amount,
                                         locksroot)
        partner_details = ParticipantDetails(
            address=participant,
            deposit=TokenAmount(5),
            withdrawn=WithdrawAmount(0),
            is_closer=True,
            balance_hash=balance_hash,
            nonce=Nonce(1),
            locksroot=LOCKSROOT_OF_NO_LOCKS,
            locked_amount=locked_amount,
        )
        return ParticipantsDetails(our_details, partner_details)
示例#4
0
def _(properties: BalanceProofSignedStateProperties,
      defaults=None) -> BalanceProofSignedState:
    defaults = defaults or BALANCE_PROOF_SIGNED_STATE_DEFAULTS
    params = _properties_to_dict(properties, defaults)
    params.update(
        _properties_to_dict(params.pop('balance_proof'),
                            defaults.balance_proof), )
    signer = LocalSigner(params.pop('pkey'))

    if params['signature'] is EMPTY:
        keys = ('transferred_amount', 'locked_amount', 'locksroot')
        balance_hash = hash_balance_data(**_partial_dict(params, *keys))

        canonical_identifier = CanonicalIdentifier(
            chain_identifier=params.pop('chain_id'),
            token_network_address=params.pop('token_network_identifier'),
            channel_identifier=params.pop('channel_identifier'),
        )
        params['canonical_identifier'] = canonical_identifier

        data_to_sign = balance_proof.pack_balance_proof(
            balance_hash=balance_hash,
            additional_hash=params['message_hash'],
            canonical_identifier=canonical_identifier,
            nonce=params.get('nonce'),
        )

        params['signature'] = signer.sign(data=data_to_sign)

    return BalanceProofSignedState(**params)
示例#5
0
    def __post_init__(self) -> None:
        typecheck(self.nonce, int)
        typecheck(self.transferred_amount, T_TokenAmount)
        typecheck(self.locked_amount, T_TokenAmount)
        typecheck(self.locksroot, T_Locksroot)

        if self.nonce <= 0:
            raise ValueError("nonce cannot be zero or negative")

        if self.nonce > UINT64_MAX:
            raise ValueError("nonce is too large")

        if self.transferred_amount < 0:
            raise ValueError("transferred_amount cannot be negative")

        if self.transferred_amount > UINT256_MAX:
            raise ValueError("transferred_amount is too large")

        if len(self.locksroot) != 32:
            raise ValueError("locksroot must have length 32")

        self.canonical_identifier.validate()

        self.balance_hash = hash_balance_data(
            transferred_amount=self.transferred_amount,
            locked_amount=self.locked_amount,
            locksroot=self.locksroot,
        )
示例#6
0
def make_signed_balance_proof_from_unsigned(
        unsigned: BalanceProofUnsignedState,
        signer: Signer) -> BalanceProofSignedState:
    balance_hash = hash_balance_data(
        transferred_amount=unsigned.transferred_amount,
        locked_amount=unsigned.locked_amount,
        locksroot=unsigned.locksroot,
    )

    additional_hash = make_additional_hash()
    data_to_sign = balance_proof.pack_balance_proof(
        balance_hash=balance_hash,
        additional_hash=additional_hash,
        canonical_identifier=unsigned.canonical_identifier,
        nonce=unsigned.nonce,
    )

    signature = signer.sign(data=data_to_sign)
    sender = signer.address

    return BalanceProofSignedState(
        nonce=unsigned.nonce,
        transferred_amount=unsigned.transferred_amount,
        locked_amount=unsigned.locked_amount,
        locksroot=unsigned.locksroot,
        message_hash=additional_hash,
        signature=signature,
        sender=sender,
        canonical_identifier=unsigned.canonical_identifier,
    )
示例#7
0
def make_signed_balance_proof(
    nonce: typing.Nonce = EMPTY,
    transferred_amount: typing.TokenAmount = EMPTY,
    locked_amount: typing.TokenAmount = EMPTY,
    token_network_address: typing.TokenNetworkID = EMPTY,
    channel_identifier: typing.ChannelID = EMPTY,
    locksroot: typing.Locksroot = EMPTY,
    extra_hash: typing.Keccak256 = EMPTY,
    private_key: bytes = EMPTY,
    sender_address: typing.Address = EMPTY,
) -> BalanceProofSignedState:

    nonce = if_empty(nonce, make_uint256())
    transferred_amount = if_empty(transferred_amount, make_uint256())
    locked_amount = if_empty(locked_amount, make_uint256())
    token_network_address = if_empty(token_network_address, make_address())
    channel_identifier = if_empty(channel_identifier, make_uint256())
    locksroot = if_empty(locksroot, make_32bytes())
    extra_hash = if_empty(extra_hash, make_keccak_hash())
    private_key = if_empty(private_key, make_privatekey())
    sender_address = if_empty(sender_address, make_address())
    signer = LocalSigner(private_key)

    balance_hash = hash_balance_data(
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
    )
    data_to_sign = balance_proof.pack_balance_proof(
        nonce=nonce,
        balance_hash=balance_hash,
        additional_hash=extra_hash,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=UNIT_CHAIN_ID,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ),
    )

    signature = signer.sign(data=data_to_sign)

    return BalanceProofSignedState(
        nonce=nonce,
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
        message_hash=extra_hash,
        signature=signature,
        sender=sender_address,
        canonical_identifier=CanonicalIdentifier(
            chain_identifier=UNIT_CHAIN_ID,
            token_network_address=token_network_address,
            channel_identifier=channel_identifier,
        ),
    )
示例#8
0
def make_signed_balance_proof(
        nonce,
        transferred_amount,
        locked_amount,
        token_network_address,
        channel_address,
        locksroot,
        extra_hash,
        private_key,
        sender_address,
):

    data_to_sign = balance_proof.signing_data(
        nonce,
        transferred_amount,
        locked_amount,
        channel_address,
        locksroot,
        extra_hash,
    )

    balance_hash = hash_balance_data(
        transferred_amount,
        locked_amount,
        locksroot,
    )
    data_to_sign = balance_proof.pack_signing_data(
        nonce=nonce,
        balance_hash=balance_hash,
        additional_hash=extra_hash,
        channel_identifier=channel_address,
        token_network_identifier=token_network_address,
        chain_id=UNIT_CHAIN_ID,
    )

    signature = signing.sign(data_to_sign, private_key)

    signed_balance_proof = BalanceProofSignedState(
        nonce,
        transferred_amount,
        locked_amount,
        locksroot,
        token_network_address,
        channel_address,
        extra_hash,
        signature,
        sender_address,
        UNIT_CHAIN_ID,
    )

    return signed_balance_proof
示例#9
0
def make_signed_balance_proof(
    nonce,
    transferred_amount,
    locked_amount,
    token_network_address,
    channel_address,
    locksroot,
    extra_hash,
    private_key,
    sender_address,
):

    data_to_sign = balance_proof.signing_data(
        nonce,
        transferred_amount,
        locked_amount,
        channel_address,
        locksroot,
        extra_hash,
    )

    balance_hash = hash_balance_data(
        transferred_amount,
        locked_amount,
        locksroot,
    )
    data_to_sign = balance_proof.pack_signing_data(
        nonce=nonce,
        balance_hash=balance_hash,
        additional_hash=extra_hash,
        channel_identifier=channel_address,
        token_network_identifier=token_network_address,
        chain_id=UNIT_CHAIN_ID,
    )

    signature = signing.sign(data_to_sign, private_key)

    signed_balance_proof = BalanceProofSignedState(
        nonce,
        transferred_amount,
        locked_amount,
        locksroot,
        token_network_address,
        channel_address,
        extra_hash,
        signature,
        sender_address,
        UNIT_CHAIN_ID,
    )

    return signed_balance_proof
示例#10
0
 def _data_to_sign(self) -> bytes:
     balance_hash = hash_balance_data(self.transferred_amount,
                                      self.locked_amount, self.locksroot)
     balance_proof_packed = pack_balance_proof(
         nonce=self.nonce,
         balance_hash=balance_hash,
         additional_hash=AdditionalHash(self.message_hash),
         canonical_identifier=CanonicalIdentifier(
             chain_identifier=self.chain_id,
             token_network_address=self.token_network_address,
             channel_identifier=self.channel_identifier,
         ),
     )
     return balance_proof_packed
示例#11
0
def make_signed_balance_proof(
        nonce: typing.Nonce = EMPTY,
        transferred_amount: typing.TokenAmount = EMPTY,
        locked_amount: typing.TokenAmount = EMPTY,
        token_network_address: typing.TokenNetworkID = EMPTY,
        channel_identifier: typing.ChannelID = EMPTY,
        locksroot: typing.Locksroot = EMPTY,
        extra_hash: typing.Keccak256 = EMPTY,
        private_key: PrivateKey = EMPTY,
        sender_address: typing.Address = EMPTY,
) -> BalanceProofSignedState:

    nonce = if_empty(nonce, make_uint256())
    transferred_amount = if_empty(transferred_amount, make_uint256())
    locked_amount = if_empty(locked_amount, make_uint256())
    token_network_address = if_empty(token_network_address, make_address())
    channel_identifier = if_empty(channel_identifier, make_uint256())
    locksroot = if_empty(locksroot, make_32bytes())
    extra_hash = if_empty(extra_hash, make_keccak_hash())
    private_key = if_empty(private_key, make_privatekey())
    sender_address = if_empty(sender_address, make_address())

    balance_hash = hash_balance_data(
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
    )
    data_to_sign = balance_proof.pack_balance_proof(
        nonce=nonce,
        balance_hash=balance_hash,
        additional_hash=extra_hash,
        channel_identifier=channel_identifier,
        token_network_identifier=token_network_address,
        chain_id=UNIT_CHAIN_ID,
    )

    signature = eth_sign(privkey=private_key, data=data_to_sign)

    return BalanceProofSignedState(
        nonce=nonce,
        transferred_amount=transferred_amount,
        locked_amount=locked_amount,
        locksroot=locksroot,
        token_network_identifier=token_network_address,
        channel_identifier=channel_identifier,
        message_hash=extra_hash,
        signature=signature,
        sender=sender_address,
        chain_id=UNIT_CHAIN_ID,
    )
示例#12
0
 def _verify_settle_state(
     self,
     transferred_amount: int,
     locked_amount: int,
     locksroot: typing.Locksroot,
     partner: typing.Address,
     partner_transferred_amount: int,
     partner_locked_amount: int,
     partner_locksroot: typing.Locksroot,
 ):
     """Check if our local state is up to date with on-chain state."""
     participant_data = self.detail_participants(self.node_address, partner)
     our_balance_hash_ok = hash_balance_data(
         transferred_amount,
         locked_amount,
         locksroot,
     ) == participant_data.our_details.balance_hash
     partner_balance_hash_ok = hash_balance_data(
         partner_transferred_amount,
         partner_locked_amount,
         partner_locksroot,
     ) == participant_data.partner_details.balance_hash
     return our_balance_hash_ok and partner_balance_hash_ok
示例#13
0
 def _data_to_sign(self) -> bytes:
     balance_hash = hash_balance_data(
         self.transferred_amount,
         self.locked_amount,
         self.locksroot,
     )
     balance_proof_packed = pack_signing_data(
         nonce=self.nonce,
         balance_hash=balance_hash,
         additional_hash=self.message_hash,
         channel_identifier=self.channel,
         token_network_identifier=self.token_network_address,
         chain_id=self.chain_id,
     )
     return balance_proof_packed
示例#14
0
 def _data_to_sign(self) -> bytes:
     balance_hash = hash_balance_data(
         self.transferred_amount,
         self.locked_amount,
         self.locksroot,
     )
     balance_proof_packed = pack_signing_data(
         nonce=self.nonce,
         balance_hash=balance_hash,
         additional_hash=self.message_hash,
         channel_identifier=self.channel_identifier,
         token_network_identifier=self.token_network_address,
         chain_id=self.chain_id,
     )
     return balance_proof_packed
示例#15
0
    def sign2(self, private_key, chain_id):
        """ Creates the signature to the balance proof. Will be used in the SC refactoring. """
        balance_hash = hash_balance_data(
            self.transferred_amount,
            self.locked_amount,
            self.locksroot,
        )
        balance_proof_packed = pack_signing_data2(
            nonce=self.nonce,
            balance_hash=balance_hash,
            additional_hash=self.message_hash.decode(),
            channel_identifier=self.channel,
            token_network_address=self.token_network_address,
            chain_id=chain_id,
        )

        self.signature = encode_hex(
            sign_data(self.privkey, balance_proof_packed),
        )
示例#16
0
    def from_balance_proof_signed_state(
        cls, balance_proof: BalanceProofSignedState
    ) -> "SignedBlindedBalanceProof":
        typecheck(balance_proof, BalanceProofSignedState)

        # pylint: disable=unexpected-keyword-arg
        return cls(
            channel_identifier=balance_proof.channel_identifier,
            token_network_address=balance_proof.token_network_address,
            nonce=balance_proof.nonce,
            additional_hash=balance_proof.message_hash,
            chain_id=balance_proof.chain_id,
            signature=balance_proof.signature,
            balance_hash=hash_balance_data(
                balance_proof.transferred_amount,
                balance_proof.locked_amount,
                balance_proof.locksroot,
            ),
        )
示例#17
0
def _(properties: BalanceProofSignedStateProperties,
      defaults=None) -> BalanceProofSignedState:
    defaults = defaults or BalanceProofSignedStateProperties.DEFAULTS
    params = create_properties(properties, defaults).__dict__
    signer = LocalSigner(params.pop("pkey"))

    if params["signature"] is GENERATE:
        keys = ("transferred_amount", "locked_amount", "locksroot")
        balance_hash = hash_balance_data(**_partial_dict(params, *keys))

        data_to_sign = balance_proof.pack_balance_proof(
            balance_hash=balance_hash,
            additional_hash=params["message_hash"],
            canonical_identifier=params["canonical_identifier"],
            nonce=params.get("nonce"),
        )

        params["signature"] = signer.sign(data=data_to_sign)

    return BalanceProofSignedState(**params)
示例#18
0
def _(properties: BalanceProofSignedStateProperties, defaults=None) -> BalanceProofSignedState:
    defaults = defaults or BALANCE_PROOF_SIGNED_STATE_DEFAULTS
    params = _properties_to_dict(properties, defaults)
    params.update(
        _properties_to_dict(params.pop('balance_proof'), defaults.balance_proof),
    )

    if params['signature'] is EMPTY:
        keys = ('transferred_amount', 'locked_amount', 'locksroot')
        balance_hash = hash_balance_data(**_partial_dict(params, *keys))

        keys = ('nonce', 'channel_identifier', 'token_network_identifier')
        data_to_sign = balance_proof.pack_balance_proof(
            balance_hash=balance_hash,
            additional_hash=params['message_hash'],
            chain_id=UNIT_CHAIN_ID,
            **_partial_dict(params, *keys),
        )

        params['signature'] = eth_sign(privkey=params.pop('pkey'), data=data_to_sign)

    return BalanceProofSignedState(**params)
示例#19
0
    def __post_init__(self) -> None:
        typecheck(self.nonce, int)
        typecheck(self.transferred_amount, T_TokenAmount)
        typecheck(self.locked_amount, T_LockedAmount)
        typecheck(self.locksroot, T_Locksroot)
        typecheck(self.message_hash, bytes)
        typecheck(self.signature, T_Signature)
        typecheck(self.sender, T_Address)

        if self.nonce <= 0:
            raise ValueError("nonce cannot be zero or negative")

        if self.nonce > UINT64_MAX:
            raise ValueError("nonce is too large")

        if self.transferred_amount < 0:
            raise ValueError("transferred_amount cannot be negative")

        if self.transferred_amount > UINT256_MAX:
            raise ValueError("transferred_amount is too large")

        if len(self.locksroot) != 32:
            raise ValueError("locksroot must have length 32")

        if len(self.message_hash) != 32:
            raise ValueError("message_hash is an invalid hash")

        if len(self.signature) != 65:
            raise ValueError("signature is an invalid signature")

        self.canonical_identifier.validate()

        self.balance_hash = hash_balance_data(
            transferred_amount=self.transferred_amount,
            locked_amount=self.locked_amount,
            locksroot=self.locksroot,
        )
示例#20
0
def _(properties: BalanceProofSignedStateProperties,
      defaults=None) -> BalanceProofSignedState:
    defaults = defaults or BALANCE_PROOF_SIGNED_STATE_DEFAULTS
    params = _properties_to_dict(properties, defaults)
    params.update(
        _properties_to_dict(params.pop('balance_proof'),
                            defaults.balance_proof), )

    if params['signature'] is EMPTY:
        keys = ('transferred_amount', 'locked_amount', 'locksroot')
        balance_hash = hash_balance_data(**_partial_dict(params, *keys))

        keys = ('nonce', 'channel_identifier', 'token_network_identifier')
        data_to_sign = balance_proof.pack_balance_proof(
            balance_hash=balance_hash,
            additional_hash=params['message_hash'],
            chain_id=UNIT_CHAIN_ID,
            **_partial_dict(params, *keys),
        )

        params['signature'] = eth_sign(privkey=params.pop('pkey'),
                                       data=data_to_sign)

    return BalanceProofSignedState(**params)
示例#21
0
文件: __init__.py 项目: sekmet/raiden
 def hash_balance_data(transferred_amount: TokenAmount,
                       locked_amount: LockedAmount,
                       locksroot: Locksroot) -> BalanceHash:
     return hash_balance_data(transferred_amount, locked_amount, locksroot)
示例#22
0
def find_max_pending_transfers(gas_limit):
    """Measure gas consumption of TokenNetwork.unlock() depending on number of
    pending transfers and find the maximum number of pending transfers so
    gas_limit is not exceeded."""

    tester = ContractTester(generate_keys=2)

    tester.deploy_contract('SecretRegistry')

    tester.deploy_contract(
        'HumanStandardToken',
        _initialAmount=100000,
        _decimalUnits=3,
        _tokenName='SomeToken',
        _tokenSymbol='SMT',
    )

    tester.deploy_contract(
        'TokenNetwork',
        _token_address=tester.contract_address('HumanStandardToken'),
        _secret_registry=tester.contract_address('SecretRegistry'),
        _chain_id=1,
        _settlement_timeout_min=100,
        _settlement_timeout_max=200,
    )

    tester.call_transaction(
        'HumanStandardToken',
        'transfer',
        _to=tester.accounts[1],
        _value=10000,
    )

    receipt = tester.call_transaction(
        'TokenNetwork',
        'openChannel',
        participant1=tester.accounts[0],
        participant2=tester.accounts[1],
        settle_timeout=150,
    )

    channel_identifier = int(hexlify(receipt['logs'][0]['topics'][1]), 16)

    tester.call_transaction(
        'HumanStandardToken',
        'approve',
        sender=tester.accounts[0],
        _spender=tester.contract_address('TokenNetwork'),
        _value=10000,
    )

    tester.call_transaction(
        'HumanStandardToken',
        'approve',
        sender=tester.accounts[1],
        _spender=tester.contract_address('TokenNetwork'),
        _value=5000,
    )

    tester.call_transaction(
        'TokenNetwork',
        'setTotalDeposit',
        channel_identifier=channel_identifier,
        participant=tester.accounts[0],
        total_deposit=5000,
        partner=tester.accounts[1],
    )

    tester.call_transaction(
        'TokenNetwork',
        'setTotalDeposit',
        channel_identifier=channel_identifier,
        participant=tester.accounts[1],
        total_deposit=2000,
        partner=tester.accounts[0],
    )

    print(
        "Measuring unlock()'s gas cost for different Merkle tree widths, can take a while..."
    )

    before_closing = tester.tester.take_snapshot()
    enough = 0
    too_much = 1024

    nonce = 10
    additional_hash = urandom(32)
    token_network_identifier = tester.contract_address('TokenNetwork')

    while enough + 1 < too_much:
        tree_size = (enough + too_much) // 2
        tester.tester.revert_to_snapshot(before_closing)

        pending_transfers_tree = get_pending_transfers_tree(
            tester.web3,
            unlockable_amounts=[1] * tree_size,
        )

        balance_hash = hash_balance_data(3000, 2000,
                                         pending_transfers_tree.merkle_root)
        data_to_sign = pack_balance_proof(
            nonce=nonce,
            balance_hash=balance_hash,
            additional_hash=additional_hash,
            channel_identifier=channel_identifier,
            token_network_identifier=token_network_identifier,
            chain_id=1,
        )
        signature = eth_sign(privkey=tester.private_keys[1], data=data_to_sign)

        tester.call_transaction(
            'TokenNetwork',
            'closeChannel',
            channel_identifier=channel_identifier,
            partner=tester.accounts[1],
            balance_hash=balance_hash,
            nonce=nonce,
            additional_hash=additional_hash,
            signature=signature,
        )

        tester.tester.mine_blocks(160)  # close settlement window

        tester.call_transaction(
            'TokenNetwork',
            'settleChannel',
            channel_identifier=channel_identifier,
            participant1=tester.accounts[0],
            participant1_transferred_amount=0,
            participant1_locked_amount=0,
            participant1_locksroot=b'\x00' * 32,
            participant2=tester.accounts[1],
            participant2_transferred_amount=3000,
            participant2_locked_amount=2000,
            participant2_locksroot=pending_transfers_tree.merkle_root,
        )

        receipt = tester.call_transaction(
            'TokenNetwork',
            'unlock',
            channel_identifier=channel_identifier,
            participant=tester.accounts[0],
            partner=tester.accounts[1],
            merkle_tree_leaves=pending_transfers_tree.packed_transfers,
        )
        gas_used = receipt['gasUsed']

        if gas_used <= gas_limit:
            enough = tree_size
            print(
                f'{tree_size} pending transfers work ({gas_used} gas needed to unlock)'
            )
        else:
            too_much = tree_size
            print(
                f'{tree_size} pending transfers are too much ({gas_used} gas needed to unlock)'
            )
示例#23
0
def find_max_pending_transfers(gas_limit):
    """Measure gas consumption of TokenNetwork.unlock() depending on number of
    pending transfers and find the maximum number of pending transfers so
    gas_limit is not exceeded."""

    tester = ContractTester(generate_keys=2)

    tester.deploy_contract('SecretRegistry')

    tester.deploy_contract(
        'HumanStandardToken',
        _initialAmount=100000,
        _decimalUnits=3,
        _tokenName='SomeToken',
        _tokenSymbol='SMT',
    )

    tester.deploy_contract(
        'TokenNetwork',
        _token_address=tester.contract_address('HumanStandardToken'),
        _secret_registry=tester.contract_address('SecretRegistry'),
        _chain_id=1,
        _settlement_timeout_min=100,
        _settlement_timeout_max=200,
    )

    tester.call_transaction(
        'HumanStandardToken',
        'transfer',
        _to=tester.accounts[1],
        _value=10000,
    )

    receipt = tester.call_transaction(
        'TokenNetwork',
        'openChannel',
        participant1=tester.accounts[0],
        participant2=tester.accounts[1],
        settle_timeout=150,
    )

    channel_identifier = int(encode_hex(receipt['logs'][0]['topics'][1]), 16)

    tester.call_transaction(
        'HumanStandardToken',
        'approve',
        sender=tester.accounts[0],
        _spender=tester.contract_address('TokenNetwork'),
        _value=10000,
    )

    tester.call_transaction(
        'HumanStandardToken',
        'approve',
        sender=tester.accounts[1],
        _spender=tester.contract_address('TokenNetwork'),
        _value=5000,
    )

    tester.call_transaction(
        'TokenNetwork',
        'setTotalDeposit',
        channel_identifier=channel_identifier,
        participant=tester.accounts[0],
        total_deposit=5000,
        partner=tester.accounts[1],
    )

    tester.call_transaction(
        'TokenNetwork',
        'setTotalDeposit',
        channel_identifier=channel_identifier,
        participant=tester.accounts[1],
        total_deposit=2000,
        partner=tester.accounts[0],
    )

    print("Measuring unlock()'s gas cost for different Merkle tree widths, can take a while...")

    before_closing = tester.tester.take_snapshot()
    enough = 0
    too_much = 1024

    nonce = 10
    additional_hash = urandom(32)
    token_network_identifier = tester.contract_address('TokenNetwork')

    while enough + 1 < too_much:
        tree_size = (enough + too_much) // 2
        tester.tester.revert_to_snapshot(before_closing)

        pending_transfers_tree = get_pending_transfers_tree(
            tester.web3,
            unlockable_amounts=[1] * tree_size,
        )

        balance_hash = hash_balance_data(3000, 2000, pending_transfers_tree.merkle_root)
        data_to_sign = pack_balance_proof(
            nonce=nonce,
            balance_hash=balance_hash,
            additional_hash=additional_hash,
            channel_identifier=channel_identifier,
            token_network_identifier=token_network_identifier,
            chain_id=1,
        )
        signature = eth_sign(privkey=tester.private_keys[1], data=data_to_sign)

        tester.call_transaction(
            'TokenNetwork',
            'closeChannel',
            channel_identifier=channel_identifier,
            partner=tester.accounts[1],
            balance_hash=balance_hash,
            nonce=nonce,
            additional_hash=additional_hash,
            signature=signature,
        )

        tester.tester.mine_blocks(160)  # close settlement window

        tester.call_transaction(
            'TokenNetwork',
            'settleChannel',
            channel_identifier=channel_identifier,
            participant1=tester.accounts[0],
            participant1_transferred_amount=0,
            participant1_locked_amount=0,
            participant1_locksroot=b'\x00' * 32,
            participant2=tester.accounts[1],
            participant2_transferred_amount=3000,
            participant2_locked_amount=2000,
            participant2_locksroot=pending_transfers_tree.merkle_root,
        )

        receipt = tester.call_transaction(
            'TokenNetwork',
            'unlock',
            channel_identifier=channel_identifier,
            participant=tester.accounts[0],
            partner=tester.accounts[1],
            merkle_tree_leaves=pending_transfers_tree.packed_transfers,
        )
        gas_used = receipt['gasUsed']

        if gas_used <= gas_limit:
            enough = tree_size
            print(f'{tree_size} pending transfers work ({gas_used} gas needed to unlock)')
        else:
            too_much = tree_size
            print(f'{tree_size} pending transfers are too much ({gas_used} gas needed to unlock)')
示例#24
0
def test_hash_balance_data(values, expected):
    assert (hash_balance_data(values[0], values[1], values[2]) == expected)
示例#25
0
def test_hash_balance_data(values, expected):
    assert(hash_balance_data(values[0], values[1], values[2]) == expected)
示例#26
0
 def balance_hash(self):
     return hash_balance_data(
         transferred_amount=self.transferred_amount,
         locked_amount=self.locked_amount,
         locksroot=self.locksroot,
     )
示例#27
0
 def balance_hash(self):
     return hash_balance_data(
         transferred_amount=self.transferred_amount,
         locked_amount=self.locked_amount,
         locksroot=self.locksroot,
     )
示例#28
0
def find_max_pending_transfers(gas_limit) -> None:
    """Measure gas consumption of TokenNetwork.unlock() depending on number of
    pending transfers and find the maximum number of pending transfers so
    gas_limit is not exceeded."""

    tester = ContractTester(generate_keys=2)

    tester.deploy_contract("SecretRegistry")

    tester.deploy_contract(
        "HumanStandardToken",
        _initialAmount=100_000,
        _decimalUnits=3,
        _tokenName="SomeToken",
        _tokenSymbol="SMT",
    )

    tester.deploy_contract(
        "TokenNetwork",
        _token_address=tester.contract_address("HumanStandardToken"),
        _secret_registry=tester.contract_address("SecretRegistry"),
        _chain_id=CHAIN_ID,
        _settlement_timeout_min=100,
        _settlement_timeout_max=200,
        _deprecation_executor=tester.accounts[0],
        _channel_participant_deposit_limit=10000,
        _token_network_deposit_limit=10000,
    )

    tester.call_transaction("HumanStandardToken",
                            "transfer",
                            _to=tester.accounts[1],
                            _value=10000)

    receipt = tester.call_transaction(
        "TokenNetwork",
        "openChannel",
        participant1=tester.accounts[0],
        participant2=tester.accounts[1],
        settle_timeout=150,
    )

    channel_identifier = ChannelID(
        int(encode_hex(receipt["logs"][0]["topics"][1]), 16))

    tester.call_transaction(
        "HumanStandardToken",
        "approve",
        sender=tester.accounts[0],
        _spender=tester.contract_address("TokenNetwork"),
        _value=10000,
    )

    tester.call_transaction(
        "HumanStandardToken",
        "approve",
        sender=tester.accounts[1],
        _spender=tester.contract_address("TokenNetwork"),
        _value=5000,
    )

    tester.call_transaction(
        "TokenNetwork",
        "setTotalDeposit",
        channel_identifier=channel_identifier,
        participant=tester.accounts[0],
        total_deposit=5000,
        partner=tester.accounts[1],
    )

    tester.call_transaction(
        "TokenNetwork",
        "setTotalDeposit",
        channel_identifier=channel_identifier,
        participant=tester.accounts[1],
        total_deposit=2000,
        partner=tester.accounts[0],
    )

    print(
        "Measuring unlock()'s gas cost for different Merkle tree widths, can take a while..."
    )

    before_closing = tester.tester.take_snapshot()
    enough = 0
    too_much = 1024

    nonce = Nonce(10)
    additional_hash = AdditionalHash(urandom(32))
    token_network_address = tester.contract_address("TokenNetwork")

    while enough + 1 < too_much:
        tree_size = (enough + too_much) // 2
        tester.tester.revert_to_snapshot(before_closing)

        pending_transfers_tree = get_pending_transfers_tree(
            tester.web3,
            unlockable_amounts=[1] * tree_size,
            expired_amounts=[])

        balance_hash = hash_balance_data(
            transferred_amount=TokenAmount(3000),
            locked_amount=TokenAmount(2000),
            locksroot=Locksroot(
                pending_transfers_tree.hash_of_packed_transfers),
        )
        canonical_identifier = CanonicalIdentifier(
            chain_identifier=CHAIN_ID,
            token_network_address=token_network_address,
            channel_identifier=ChannelID(channel_identifier),
        )
        data_to_sign = pack_balance_proof(
            nonce=Nonce(nonce),
            balance_hash=balance_hash,
            additional_hash=additional_hash,
            canonical_identifier=canonical_identifier,
        )
        signature = LocalSigner(tester.private_keys[1]).sign(data=data_to_sign)

        tester.call_transaction(
            "TokenNetwork",
            "closeChannel",
            channel_identifier=channel_identifier,
            partner=tester.accounts[1],
            balance_hash=balance_hash,
            nonce=nonce,
            additional_hash=additional_hash,
            signature=signature,
        )

        tester.tester.mine_blocks(160)  # close settlement window

        tester.call_transaction(
            "TokenNetwork",
            "settleChannel",
            channel_identifier=channel_identifier,
            participant1=tester.accounts[0],
            participant1_transferred_amount=0,
            participant1_locked_amount=0,
            participant1_locksroot=b"\x00" * 32,
            participant2=tester.accounts[1],
            participant2_transferred_amount=3000,
            participant2_locked_amount=2000,
            participant2_locksroot=pending_transfers_tree.
            hash_of_packed_transfers,
        )

        receipt = tester.call_transaction(
            "TokenNetwork",
            "unlock",
            channel_identifier=channel_identifier,
            participant=tester.accounts[0],
            partner=tester.accounts[1],
            merkle_tree_leaves=pending_transfers_tree.packed_transfers,
        )
        gas_used = receipt["gasUsed"]

        if gas_used <= gas_limit:
            enough = tree_size
            print(
                f"{tree_size} pending transfers work ({gas_used} gas needed to unlock)"
            )
        else:
            too_much = tree_size
            print(
                f"{tree_size} pending transfers are too much ({gas_used} gas needed to unlock)"
            )