Beispiel #1
0
    async def _do_open_channel(self, market_oid, channel_oid, channel_type,
                               delegate, amount):
        member_key = self._ethkey_raw
        member_adr = self._ethkey.public_key.to_canonical_address()

        config = await self.call('xbr.marketmaker.get_config')
        marketmaker = config['marketmaker']
        recipient = config['owner']
        verifying_chain_id = config['verifying_chain_id']
        verifying_contract_adr = binascii.a2b_hex(
            config['verifying_contract_adr'][2:])

        status = await self.call('xbr.marketmaker.get_status')
        current_block_number = status['block']['number']

        if amount > 0:
            if channel_type == ChannelType.PAYMENT:
                allowance1 = xbr.xbrtoken.functions.allowance(
                    member_adr, xbr.xbrchannel.address).call()
                xbr.xbrtoken.functions.approve(xbr.xbrchannel.address,
                                               amount).transact({
                                                   'from':
                                                   member_adr,
                                                   'gas':
                                                   self._default_gas
                                               })
                allowance2 = xbr.xbrtoken.functions.allowance(
                    member_adr, xbr.xbrchannel.address).call()
                assert allowance2 - allowance1 == amount
            elif channel_type == ChannelType.PAYING:
                allowance1 = xbr.xbrtoken.functions.allowance(
                    marketmaker, xbr.xbrchannel.address).call()
                xbr.xbrtoken.functions.approve(xbr.xbrchannel.address,
                                               amount).transact({
                                                   'from':
                                                   marketmaker,
                                                   'gas':
                                                   self._default_gas
                                               })
                allowance2 = xbr.xbrtoken.functions.allowance(
                    marketmaker, xbr.xbrchannel.address).call()
                assert allowance2 - allowance1 == amount
            else:
                assert False, 'should not arrive here'

        # compute EIP712 signature, and sign using member private key
        signature = sign_eip712_channel_open(
            member_key, verifying_chain_id, verifying_contract_adr,
            channel_type, current_block_number, market_oid.bytes,
            channel_oid.bytes, member_adr, delegate, marketmaker, recipient,
            amount)
        attributes = None
        channel_request = await self.call(
            'xbr.marketmaker.open_channel', member_adr, market_oid.bytes,
            channel_oid.bytes, verifying_chain_id, current_block_number,
            verifying_contract_adr, channel_type, delegate, marketmaker,
            recipient, pack_uint256(amount), signature, attributes)

        self.log.info('Channel open request submitted:\n\n{channel_request}\n',
                      channel_request=pformat(channel_request))
Beispiel #2
0
    def _process_block(self, w3, block_number, Events):
        """

        :param w3:
        :param block_number:
        :param Events:
        :return:
        """
        cnt = 0
        # filter by block, and XBR contract addresses
        # FIXME: potentially add filters for global data or market specific data for the markets started in this worker
        filter_params = {
            'address': [
                xbr.xbrtoken.address, xbr.xbrnetwork.address, xbr.xbrcatalog.address, xbr.xbrmarket.address,
                xbr.xbrchannel.address
            ],
            'fromBlock':
            block_number,
            'toBlock':
            block_number,
        }
        result = w3.eth.getLogs(filter_params)
        if result:
            for evt in result:
                receipt = w3.eth.getTransactionReceipt(evt['transactionHash'])
                for Event, handler in Events:
                    # FIXME: MismatchedABI pops up .. we silence this with errors=web3.logs.DISCARD
                    if hasattr(web3, 'logs') and web3.logs:
                        all_res = Event().processReceipt(receipt, errors=web3.logs.DISCARD)
                    else:
                        all_res = Event().processReceipt(receipt)
                    for res in all_res:
                        self.log.info('{handler} processing block {block_number} / txn {txn} with args {args}',
                                      handler=hl(handler.__name__),
                                      block_number=hlid(block_number),
                                      txn=hlid('0x' + binascii.b2a_hex(evt['transactionHash']).decode()),
                                      args=hlval(res.args))
                        handler(res.transactionHash, res.blockHash, res.args)
                        cnt += 1

        with self._db.begin(write=True) as txn:
            block = cfxdb.xbr.block.Block()
            block.timestamp = np.datetime64(time_ns(), 'ns')
            block.block_number = block_number
            # FIXME
            # block.block_hash = bytes()
            block.cnt_events = cnt
            self._xbr.blocks[txn, pack_uint256(block_number)] = block

        if cnt:
            self.log.info('Processed blockchain block {block_number}: processed {cnt} XBR events.',
                          block_number=hlid(block_number),
                          cnt=hlid(cnt))
        else:
            self.log.info('Processed blockchain block {block_number}: no XBR events found!',
                          block_number=hlid(block_number))

        return cnt
Beispiel #3
0
    async def _do_open_channel(self, market_oid, channel_oid, channel_type, delegate, amount):
        member_key = self._ethkey_raw
        member_adr = self._ethkey.public_key.to_canonical_address()

        config = await self.call('xbr.marketmaker.get_config')
        marketmaker = binascii.a2b_hex(config['marketmaker'][2:])
        recipient = binascii.a2b_hex(config['owner'][2:])
        verifying_chain_id = config['verifying_chain_id']
        verifying_contract_adr = binascii.a2b_hex(config['verifying_contract_adr'][2:])

        status = await self.call('xbr.marketmaker.get_status')
        current_block_number = status['block']['number']

        if amount > 0:
            if channel_type == ChannelType.PAYMENT:
                from_adr = member_adr
                to_adr = xbr.xbrchannel.address
            elif channel_type == ChannelType.PAYING:
                from_adr = marketmaker
                to_adr = xbr.xbrchannel.address
            else:
                assert False, 'should not arrive here'

            # allowance1 = xbr.xbrtoken.functions.allowance(transact_from, xbr.xbrchannel.address).call()
            # xbr.xbrtoken.functions.approve(to_adr, amount).transact(
            #     {'from': transact_from, 'gas': transact_gas})
            # allowance2 = xbr.xbrtoken.functions.allowance(transact_from, xbr.xbrchannel.address).call()
            # assert allowance2 - allowance1 == amount

            try:
                txn_hash = await deferToThread(self._send_Allowance, from_adr, to_adr, amount)
                self.log.info('transaction submitted, txn_hash={txn_hash}', txn_hash=txn_hash)
            except Exception as e:
                self.log.failure()
                raise e

        # compute EIP712 signature, and sign using member private key
        signature = sign_eip712_channel_open(member_key, verifying_chain_id, verifying_contract_adr, channel_type,
                                             current_block_number, market_oid.bytes, channel_oid.bytes,
                                             member_adr, delegate, marketmaker, recipient, amount)
        attributes = None
        channel_request = await self.call('xbr.marketmaker.open_channel', member_adr, market_oid.bytes,
                                          channel_oid.bytes, verifying_chain_id, current_block_number,
                                          verifying_contract_adr, channel_type, delegate, marketmaker, recipient,
                                          pack_uint256(amount), signature, attributes)

        self.log.info('Channel open request submitted:\n\n{channel_request}\n',
                      channel_request=pformat(channel_request))
Beispiel #4
0
    async def onJoin(self, details):
        self.log.info('{klass}.onJoin(details={details})', klass=self.__class__.__name__, details=details)

        try:
            assert details.authrole == 'member'

            # WAMP authid on xbrnetwork follows this format: "member-"
            member_id = details.authid[7:]
            member_id = UUID(member_id)

            member_data = await self.call('xbr.network.get_member', member_id.bytes)
            member_adr = member_data['address']

            config = await self.call('xbr.network.get_config')

            verifyingChain = config['verifying_chain_id']
            verifyingContract = binascii.a2b_hex(config['verifying_contract_adr'][2:])

            coin_adr = binascii.a2b_hex(config['contracts']['xbrtoken'][2:])

            status = await self.call('xbr.network.get_status')
            block_number = status['block']['number']

            # count all markets before we create a new one:
            res = await self.call('xbr.network.find_markets')
            cnt_market_before = len(res)

            res = await self.call('xbr.network.get_markets_by_owner', member_id.bytes)
            cnt_market_by_owner_before = len(res)

            # create a new market ..
            market_oid = uuid.uuid4()

            # collect information for market creation that is stored on-chain

            # terms text: encode in utf8 and compute BIP58 multihash string
            terms_data = 'these are my market terms (randint={})'.format(random.randint(0, 1000)).encode('utf8')
            h = hashlib.sha256()
            h.update(terms_data)
            terms_hash = str(multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256')))

            # market maker address
            maker = os.urandom(20)

            # provider and consumer security
            provider_security = 0 * 10**18
            consumer_security = 0 * 10**18

            # market operator fee
            market_fee = 0 * 10**18

            # market meta data that doesn't change. the hash of this is part of the data that is signed and also
            # stored on-chain (only the hash, not the meta data!)
            meta_obj = {
                'chain_id': verifyingChain,
                'block_number': block_number,
                'contract_adr': verifyingContract,
                'member_adr': member_adr,
                'member_oid': member_id.bytes,
                'market_oid': market_oid.bytes,
            }
            meta_data = cbor2.dumps(meta_obj)
            h = hashlib.sha256()
            h.update(meta_data)
            meta_hash = multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256'))

            # create signature for pre-signed transaction
            signature = sign_eip712_market_create(self._ethkey_raw, verifyingChain, verifyingContract, member_adr,
                                                  block_number, market_oid.bytes, coin_adr, terms_hash, meta_hash,
                                                  maker, provider_security, consumer_security, market_fee)

            # for wire transfer, convert to bytes
            provider_security = pack_uint256(provider_security)
            consumer_security = pack_uint256(consumer_security)
            market_fee = pack_uint256(market_fee)

            # market settings that can change. even though changing might require signing, neither the data nor
            # and signatures are stored on-chain. however, even when only signed off-chain, this establishes
            # a chain of signature anchored in the on-chain record for this market!
            attributes = {
                'title': 'International Data Monetization Award',
                'label': 'IDMA',
                'homepage': 'https://markets.international-data-monetization-award.com/',
            }

            # now provide everything of above:
            #   - market operator (owning member) and market oid
            #   - signed market data and signature
            #   - settings
            createmarket_request_submitted = await self.call('xbr.network.create_market', member_id.bytes,
                                                             market_oid.bytes, verifyingChain, block_number,
                                                             verifyingContract, coin_adr, terms_hash, meta_hash,
                                                             meta_data, maker, provider_security, consumer_security,
                                                             market_fee, signature, attributes)

            self.log.info('Create market request submitted: \n{createmarket_request_submitted}\n',
                          createmarket_request_submitted=pformat(createmarket_request_submitted))

            assert type(createmarket_request_submitted) == dict
            assert 'timestamp' in createmarket_request_submitted and type(
                createmarket_request_submitted['timestamp']) == int and createmarket_request_submitted['timestamp'] > 0
            assert 'action' in createmarket_request_submitted and createmarket_request_submitted[
                'action'] == 'create_market'
            assert 'vaction_oid' in createmarket_request_submitted and type(
                createmarket_request_submitted['vaction_oid']) == bytes and len(
                    createmarket_request_submitted['vaction_oid']) == 16

            vaction_oid = UUID(bytes=createmarket_request_submitted['vaction_oid'])
            self.log.info('Create market verification "{vaction_oid}" created', vaction_oid=vaction_oid)

            # fd = 'cloud/planet_xbr_crossbar/.crossbar/.verifications'
            fd = self._verifications
            if not os.path.isdir(fd):
                os.mkdir(fd)
            fn = 'create-market-email-verification.{}'.format(vaction_oid)
            verification_file = os.path.abspath(os.path.join(fd, fn))
            with open(verification_file, 'rb') as f:
                data = f.read()
                verified_data = cbor2.loads(data)

            self.log.info('Verified data:\n{verified_data}', verified_data=verified_data)

            vaction_code = verified_data['vcode']

            self.log.info('Verifying create market using vaction_oid={vaction_oid}, vaction_code={vaction_code} ..',
                          vaction_oid=vaction_oid,
                          vaction_code=vaction_code)

            create_market_request_verified = await self.call('xbr.network.verify_create_market', vaction_oid.bytes,
                                                             vaction_code)

            self.log.info('Create market request verified: \n{create_market_request_verified}\n',
                          create_market_request_verified=pformat(create_market_request_verified))

            assert type(create_market_request_verified) == dict
            assert 'market_oid' in create_market_request_verified and type(
                create_market_request_verified['market_oid']) == bytes and len(
                    create_market_request_verified['market_oid']) == 16
            assert 'created' in create_market_request_verified and type(
                create_market_request_verified['created']) == int and create_market_request_verified['created'] > 0

            market_oid = create_market_request_verified['market_oid']
            self.log.info('SUCCESS! New XBR market created: market_oid={market_oid}, result=\n{result}',
                          market_oid=UUID(bytes=market_oid),
                          result=pformat(create_market_request_verified))

            market_oids = await self.call('xbr.network.find_markets')
            self.log.info('SUCCESS - find_markets: found {cnt_markets} markets', cnt_markets=len(market_oids))

            # count all markets after we created a new market:
            cnt_market_after = len(market_oids)
            cnt_new_markets = cnt_market_after - cnt_market_before

            assert cnt_new_markets == 1, 'expected 1 market, but found {} new ones!'.format(cnt_new_markets)
            assert market_oid in market_oids, 'expected to find market ID {}, but not found in {} returned market IDs'.format(
                UUID(bytes=market_oid), len(market_oids))

            market_oids = await self.call('xbr.network.get_markets_by_owner', member_id.bytes)
            self.log.info('SUCCESS - get_markets_by_owner: found {cnt_markets} markets', cnt_markets=len(market_oids))

            # count all markets after we created a new market:
            cnt_market_by_owner_after = len(market_oids)
            cnt_new_markets_by_owner = cnt_market_by_owner_after - cnt_market_by_owner_before

            assert cnt_new_markets_by_owner == 1, 'expected 1 market, but found {} new ones!'.format(
                cnt_new_markets_by_owner)
            assert market_oid in market_oids, 'expected to find market ID {}, but not found in {} returned market IDs'.format(
                UUID(bytes=market_oid), len(market_oids))

            for market_oid in market_oids:
                self.log.info('xbr.network.get_market(market_oid={market_oid}) ..', market_oid=market_oid)
                market = await self.call('xbr.network.get_market', market_oid, include_attributes=True)
                self.log.info('SUCCESS: got market information\n\n{market}\n', market=pformat(market))

        except Exception as e:
            self.log.failure()
            self.config.extra['error'] = e
        finally:
            self.leave()
Beispiel #5
0
    def build(self, builder):

        oid = self.oid.bytes if self.oid else None
        if oid:
            oid = builder.CreateString(oid)

        username = self.username
        if username:
            username = builder.CreateString(username)

        email = self.email
        if email:
            email = builder.CreateString(email)

        wallet_address = self.wallet_address
        if wallet_address:
            wallet_address = builder.CreateString(wallet_address)

        registered = self.registered
        if registered:
            registered = builder.CreateString(pack_uint256(registered))

        eula = self.eula
        if eula:
            eula = builder.CreateString(eula)

        profile = self.profile
        if profile:
            profile = builder.CreateString(profile)

        AccountGen.AccountStart(builder)

        if oid:
            AccountGen.AccountAddOid(builder, oid)

        if self.created:
            AccountGen.AccountAddCreated(builder, int(self.created))

        if username:
            AccountGen.AccountAddUsername(builder, username)

        if email:
            AccountGen.AccountAddEmail(builder, email)

        if self.email_verified:
            AccountGen.AccountAddEmailVerified(builder,
                                               int(self.email_verified))

        if self.wallet_type:
            AccountGen.AccountAddWalletType(builder, self.wallet_type)

        if wallet_address:
            AccountGen.AccountAddWalletAddress(builder, wallet_address)

        if registered:
            AccountGen.AccountAddRegistered(builder, registered)

        if eula:
            AccountGen.AccountAddEula(builder, eula)

        if profile:
            AccountGen.AccountAddProfile(builder, profile)

        if self.level:
            AccountGen.AccountAddLevel(builder, self.level)

        final = AccountGen.AccountEnd(builder)

        return final
Beispiel #6
0
    async def _do_create_market(self, member_oid, market_oid, marketmaker, title=None, label=None, homepage=None,
                                provider_security=0, consumer_security=0, market_fee=0):
        member_data = await self.call('network.xbr.console.get_member', member_oid.bytes)
        member_adr = member_data['address']

        config = await self.call('network.xbr.console.get_config')

        verifyingChain = config['verifying_chain_id']
        verifyingContract = binascii.a2b_hex(config['verifying_contract_adr'][2:])

        coin_adr = binascii.a2b_hex(config['contracts']['xbrtoken'][2:])

        status = await self.call('network.xbr.console.get_status')
        block_number = status['block']['number']

        # count all markets before we create a new one:
        res = await self.call('network.xbr.console.find_markets')
        cnt_market_before = len(res)
        self.log.info('Total markets before: {cnt_market_before}', cnt_market_before=cnt_market_before)

        res = await self.call('network.xbr.console.get_markets_by_owner', member_oid.bytes)
        cnt_market_by_owner_before = len(res)
        self.log.info('Market for owner: {cnt_market_by_owner_before}',
                      cnt_market_by_owner_before=cnt_market_by_owner_before)

        # collect information for market creation that is stored on-chain

        # terms text: encode in utf8 and compute BIP58 multihash string
        terms_data = 'these are my market terms (randint={})'.format(random.randint(0, 1000)).encode('utf8')
        h = hashlib.sha256()
        h.update(terms_data)
        terms_hash = str(multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256')))

        # market meta data that doesn't change. the hash of this is part of the data that is signed and also
        # stored on-chain (only the hash, not the meta data!)
        meta_obj = {
            'chain_id': verifyingChain,
            'block_number': block_number,
            'contract_adr': verifyingContract,
            'member_adr': member_adr,
            'member_oid': member_oid.bytes,
            'market_oid': market_oid.bytes,
        }
        meta_data = cbor2.dumps(meta_obj)
        h = hashlib.sha256()
        h.update(meta_data)
        meta_hash = multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256'))

        # create signature for pre-signed transaction
        signature = sign_eip712_market_create(self._ethkey_raw, verifyingChain, verifyingContract, member_adr,
                                              block_number, market_oid.bytes, coin_adr, terms_hash, meta_hash,
                                              marketmaker, provider_security, consumer_security, market_fee)

        # for wire transfer, convert to bytes
        provider_security = pack_uint256(provider_security)
        consumer_security = pack_uint256(consumer_security)
        market_fee = pack_uint256(market_fee)

        # market settings that can change. even though changing might require signing, neither the data nor
        # and signatures are stored on-chain. however, even when only signed off-chain, this establishes
        # a chain of signature anchored in the on-chain record for this market!
        attributes = {
            'title': title,
            'label': label,
            'homepage': homepage,
        }

        # now provide everything of above:
        #   - market operator (owning member) and market oid
        #   - signed market data and signature
        #   - settings
        createmarket_request_submitted = await self.call('network.xbr.console.create_market', member_oid.bytes,
                                                         market_oid.bytes, verifyingChain, block_number,
                                                         verifyingContract, coin_adr, terms_hash, meta_hash, meta_data,
                                                         marketmaker, provider_security, consumer_security, market_fee,
                                                         signature, attributes)

        self.log.info('SUCCESS: Create market request submitted: \n{createmarket_request_submitted}\n',
                      createmarket_request_submitted=pformat(createmarket_request_submitted))

        assert type(createmarket_request_submitted) == dict
        assert 'timestamp' in createmarket_request_submitted and type(
            createmarket_request_submitted['timestamp']) == int and createmarket_request_submitted['timestamp'] > 0
        assert 'action' in createmarket_request_submitted and createmarket_request_submitted[
            'action'] == 'create_market'
        assert 'vaction_oid' in createmarket_request_submitted and type(
            createmarket_request_submitted['vaction_oid']) == bytes and len(
            createmarket_request_submitted['vaction_oid']) == 16

        vaction_oid = uuid.UUID(bytes=createmarket_request_submitted['vaction_oid'])
        self.log.info('SUCCESS: New Market verification "{vaction_oid}" created', vaction_oid=vaction_oid)