def get_request_monitoring( self, privkey: str, reward_amount: TokenAmount, monitoring_service_contract_address: Address, ) -> RequestMonitoring: """Returns raiden client's RequestMonitoring object""" non_closing_signer = LocalSigner(decode_hex(privkey)) partner_signed_self = SignedBlindedBalanceProof( channel_identifier=self.channel_identifier, token_network_address=self.token_network_address, nonce=self.nonce, additional_hash=AdditionalHash(decode_hex(self.additional_hash)), chain_id=self.chain_id, signature=self.signature, balance_hash=BalanceHash(decode_hex(self.balance_hash)), ) request_monitoring = RequestMonitoring( balance_proof=partner_signed_self, non_closing_participant=privatekey_to_address(decode_hex(privkey)), reward_amount=reward_amount, signature=EMPTY_SIGNATURE, monitoring_service_contract_address= monitoring_service_contract_address, ) request_monitoring.sign(non_closing_signer) return request_monitoring
def serialize_bin( self, msg_type: MessageTypeId = MessageTypeId.BALANCE_PROOF) -> bytes: return pack_balance_proof( to_checksum_address(self.token_network_address), self.chain_id, self.channel_identifier, BalanceHash(decode_hex(self.balance_hash)), self.nonce, AdditionalHash(decode_hex(self.additional_hash)), msg_type, )
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
def balanceproof_from_envelope(envelope_message: EnvelopeMessage) -> BalanceProofSignedState: assert envelope_message.sender, "envelope_message must be signed" return BalanceProofSignedState( nonce=envelope_message.nonce, transferred_amount=envelope_message.transferred_amount, locked_amount=envelope_message.locked_amount, locksroot=envelope_message.locksroot, message_hash=AdditionalHash(envelope_message.message_hash), signature=envelope_message.signature, sender=envelope_message.sender, canonical_identifier=CanonicalIdentifier( chain_identifier=envelope_message.chain_id, token_network_address=envelope_message.token_network_address, channel_identifier=envelope_message.channel_identifier, ), )
def make_signed_balance_proof_from_counter(counter): lock = Lock( amount=next(counter), expiration=next(counter), secrethash=factories.make_secret_hash(next(counter)), ) lock_expired_balance_proof = factories.create( factories.BalanceProofSignedStateProperties( nonce=next(counter), transferred_amount=next(counter), locked_amount=next(counter), canonical_identifier=factories.make_canonical_identifier( token_network_address=factories.make_address(), channel_identifier=next(counter)), locksroot=Locksroot(sha3(lock.as_bytes)), message_hash=AdditionalHash(sha3(b"")), sender=factories.HOP1, pkey=factories.HOP1_KEY, )) return lock_expired_balance_proof
RED_EYES_PER_CHANNEL_PARTICIPANT_LIMIT = int(0.075 * 10**18) RED_EYES_PER_TOKEN_NETWORK_LIMIT = int(250 * 10**18) GENESIS_BLOCK_NUMBER = BlockNumber(0) # Set at 64 since parity's default is 64 and Geth's default is 128 # TODO: Make this configurable. Since in parity this is also a configurable value STATE_PRUNING_AFTER_BLOCKS = 64 STATE_PRUNING_SAFETY_MARGIN = 8 NO_STATE_QUERY_AFTER_BLOCKS = STATE_PRUNING_AFTER_BLOCKS - STATE_PRUNING_SAFETY_MARGIN NULL_ADDRESS_BYTES = bytes(20) NULL_ADDRESS = to_checksum_address(NULL_ADDRESS_BYTES) EMPTY_HASH = BlockHash(bytes(32)) EMPTY_BALANCE_HASH = BalanceHash(bytes(32)) EMPTY_MESSAGE_HASH = AdditionalHash(bytes(32)) EMPTY_HASH_KECCAK = keccak(EMPTY_HASH) EMPTY_SIGNATURE = Signature(bytes(65)) EMPTY_MERKLE_ROOT = Locksroot(bytes(32)) EMPTY_SECRET = Secret(b"") ZERO_TOKENS = TokenAmount(0) SECRET_HEXSTRING_LENGTH = len(to_hex(EMPTY_HASH)) SECRETHASH_HEXSTRING_LENGTH = SECRET_HEXSTRING_LENGTH RECEIPT_FAILURE_CODE = 0 class EthClient(Enum): GETH = "geth" PARITY = "parity"
def make_additional_hash() -> AdditionalHash: return AdditionalHash(make_32bytes())
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)" )