def test_from_digest_string_valid(self, value): """ from_hex_string: decodes the correct values """ code = value['encoding']['code'] buffer = encode(bytes.fromhex(value['hex']), code) assert from_hex_string(hexlify(buffer).decode()) == buffer
import hashlib import multihash from topo_processor.file_system.get_fs import get_fs CHUNK_SIZE = 1024 * 1024 # 1MB async def multihash_as_hex(path: str) -> str: file_hash = hashlib.sha256() with get_fs(path).open(path, "rb") as file: while chunk := file.read(CHUNK_SIZE): file_hash.update(chunk) return multihash.to_hex_string( multihash.encode(file_hash.digest(), "sha2-256"))
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:]) # remember the number of markets we joined before markets_by_actor_before = await self.call( 'xbr.network.get_markets_by_actor', member_id.bytes) cnt_markets_by_actor_before = len(markets_by_actor_before) # join the first market we find market_oids = await self.call('xbr.network.find_markets') assert len(market_oids ) > 0, 'fatal: no markets defined that we could join' marketId = market_oids[0] for actorType in [ActorType.PROVIDER, ActorType.CONSUMER]: status = await self.call('xbr.network.get_status') block_number = status['block']['number'] meta_obj = {} 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')) signature = sign_eip712_market_join( self._ethkey_raw, verifyingChain, verifyingContract, member_adr, block_number, marketId, actorType, meta_hash) request_submitted = await self.call( 'xbr.network.join_market', member_id.bytes, marketId, verifyingChain, block_number, verifyingContract, actorType, meta_hash, meta_data, signature) self.log.info( 'Join market request submitted (actorType={actorType}, member_id={member_id}, member_adr=0x{member_adr}): \n{request_submitted}\n', member_id=member_id, actorType=actorType, member_adr=binascii.b2a_hex(member_adr).decode(), request_submitted=pformat(request_submitted)) assert type(request_submitted) == dict assert 'created' in request_submitted and type( request_submitted['created'] ) == int and request_submitted['created'] > 0 assert 'action' in request_submitted and request_submitted[ 'action'] == 'join_market' assert 'vaction_oid' in request_submitted and type( request_submitted['vaction_oid']) == bytes and len( request_submitted['vaction_oid']) == 16 vaction_oid = UUID(bytes=request_submitted['vaction_oid']) self.log.info( 'Join 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 = 'join-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 join market using vaction_oid={vaction_oid}, vaction_code={vaction_code} ..', vaction_oid=vaction_oid, vaction_code=vaction_code) request_verified = await self.call( 'xbr.network.verify_join_market', vaction_oid.bytes, vaction_code) self.log.info( 'Join market request verified: \n{request_verified}\n', request_verified=pformat(request_verified)) assert type(request_verified) == dict assert 'market_oid' in request_verified and type( request_verified['market_oid']) == bytes and len( request_verified['market_oid']) == 16 assert 'created' in request_verified and type( request_verified['created'] ) == int and request_verified['created'] > 0 market_oid = request_verified['market_oid'] self.log.info( 'SUCCESS! XBR market joined: market_oid={market_oid}, actor_type={actor_type}, result=\n{result}', market_oid=UUID(bytes=market_oid), actor_type=actorType, result=pformat(request_verified)) markets_by_actor_after = await self.call( 'xbr.network.get_markets_by_actor', member_id.bytes) cnt_markets_by_actor_after = len(markets_by_actor_after) cnt_new_joins = cnt_markets_by_actor_after - cnt_markets_by_actor_before print('markets_by_actor_before: ', markets_by_actor_before) print('markets_by_actor_after: ', markets_by_actor_after) print('cnt_markets_by_actor_before: ', cnt_markets_by_actor_before) print('cnt_markets_by_actor_after: ', cnt_markets_by_actor_after) print('cnt_new_joins: ', cnt_new_joins) # assert cnt_new_joins == 1, 'expected 1 market, but found {} new ones!'.format(cnt_new_joins) # 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)) except Exception as e: self.log.failure() self.config.extra['error'] = e finally: self.leave()
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()
def test_valid_prefix(self): mhash = multihash.encode(b'hey', 0x11, 3) prefix = multihash.prefix(mhash) assert hexlify(prefix).decode() == '1103'
def file_multihash(file_path): h = file_sha_256(file_path) encoded = multihash.encode(h, multihash.SHA2_256) return base58.b58encode(str(encoded))
def _random_multihash(): digest = str(uuid.uuid4()).encode() return multihash.to_b58_string(multihash.encode(digest, 'sha2-256'))
def make_hash(object_bytes): hasher = sha256() hasherm.update(object_bytes) return b58encode( bytes(multihash.encode(hasher.digest(), multihash.SHA2_256)))
def _gen_ipfs_hash(): # IPFS uses sha2-256 and B58 string encoding, eg "QmevbQAb6L7MsZUxqsspYREqMhMqaaV6arvF4UytgdsSfX" data = os.urandom(100) digest = hashlib.sha256(data).digest() hash = multihash.encode(digest, 'sha2-256') return multihash.to_b58_string(hash)
def make_cbor_sha256_multihash(obj: object) -> bytes: cbor_obj = make_cbor(obj) hash_digest = hashlib.sha256(cbor_obj).digest() return multihash.encode(hash_digest, "sha2-256")
async def onJoin(self, details): self.log.info('{klass}.onJoin(details={details})', klass=self.__class__.__name__, details=details) try: member_username = self.config.extra['username'] member_email = self.config.extra['email'] client_pubkey = binascii.a2b_hex(self._key.public_key()) # fake wallet type "metamask" wallet_type = 'metamask' # delegate ethereum private key object wallet_key = self._ethkey wallet_raw = self._ethkey_raw # delegate ethereum account canonical address wallet_adr = wallet_key.public_key.to_canonical_address() config = await self.call('xbr.network.get_config') status = await self.call('xbr.network.get_status') verifyingChain = config['verifying_chain_id'] verifyingContract = binascii.a2b_hex(config['verifying_contract_adr'][2:]) registered = status['block']['number'] eula = config['eula']['hash'] # create an aux-data object with info only stored off-chain (in our xbrbackend DB) .. profile_obj = { 'member_username': member_username, 'member_email': member_email, 'client_pubkey': client_pubkey, 'wallet_type': wallet_type, } # .. hash the serialized aux-data object .. profile_data = cbor2.dumps(profile_obj) h = hashlib.sha256() h.update(profile_data) # .. compute the sha256 multihash b58-encoded string from that .. profile = multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256')) signature = sign_eip712_member_register(wallet_raw, verifyingChain, verifyingContract, wallet_adr, registered, eula, profile) # https://xbr.network/docs/network/api.html#xbrnetwork.XbrNetworkApi.onboard_member try: result = await self.call('xbr.network.onboard_member', member_username, member_email, client_pubkey, wallet_type, wallet_adr, verifyingChain, registered, verifyingContract, eula, profile, profile_data, signature) except ApplicationError as e: self.log.error('ApplicationError: {error}', error=e) self.leave('wamp.error', str(e)) return except Exception as e: raise e assert type(result) == dict assert 'timestamp' in result and type(result['timestamp']) == int and result['timestamp'] > 0 assert 'action' in result and result['action'] == 'onboard_member' assert 'vaction_oid' in result and type(result['vaction_oid']) == bytes and len( result['vaction_oid']) == 16 vaction_oid = uuid.UUID(bytes=result['vaction_oid']) self.log.info('On-boarding member - 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 = 'onboard-member-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['onboard_vcode'] self.log.info('Verifying member using vaction_oid={vaction_oid}, vaction_code={vaction_code} ..', vaction_oid=vaction_oid, vaction_code=vaction_code) try: result = await self.call('xbr.network.verify_onboard_member', vaction_oid.bytes, vaction_code) except ApplicationError as e: self.log.error('ApplicationError: {error}', error=e) raise e assert type(result) == dict assert 'member_oid' in result and type(result['member_oid']) == bytes and len(result['member_oid']) == 16 assert 'created' in result and type(result['created']) == int and result['created'] > 0 member_oid = result['member_oid'] self.log.info('SUCCESS! New XBR Member onboarded: member_oid={member_oid}, result=\n{result}', member_oid=uuid.UUID(bytes=member_oid), result=pformat(result)) except Exception as e: self.log.failure() self.config.extra['error'] = e finally: self.leave()
def getXorAddresOfMutable(data, ffi): xorName_asBytes = ffi.buffer(data.name)[:] myHash = multihash.encode(xorName_asBytes, 'sha3-256') myCid = cid.make_cid(1, 'dag-pb', myHash) encodedAddress = myCid.encode('base16').decode() return 'safe://' + encodedAddress + ':' + str(data.type_tag)
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)
async def _do_onboard_member(self, member_username, member_email): client_pubkey = binascii.a2b_hex(self._key.public_key()) # fake wallet type "metamask" wallet_type = 'metamask' # delegate ethereum private key object wallet_key = self._ethkey wallet_raw = self._ethkey_raw # delegate ethereum account canonical address wallet_adr = wallet_key.public_key.to_canonical_address() config = await self.call('network.xbr.console.get_config') status = await self.call('network.xbr.console.get_status') verifyingChain = config['verifying_chain_id'] verifyingContract = binascii.a2b_hex(config['verifying_contract_adr'][2:]) registered = status['block']['number'] eula = config['eula']['hash'] # create an aux-data object with info only stored off-chain (in our xbrbackend DB) .. profile_obj = { 'member_username': member_username, 'member_email': member_email, 'client_pubkey': client_pubkey, 'wallet_type': wallet_type, } # .. hash the serialized aux-data object .. profile_data = cbor2.dumps(profile_obj) h = hashlib.sha256() h.update(profile_data) # .. compute the sha256 multihash b58-encoded string from that .. profile = multihash.to_b58_string(multihash.encode(h.digest(), 'sha2-256')) signature = sign_eip712_member_register(wallet_raw, verifyingChain, verifyingContract, wallet_adr, registered, eula, profile) # https://xbr.network/docs/network/api.html#xbrnetwork.XbrNetworkApi.onboard_member try: result = await self.call('network.xbr.console.onboard_member', member_username, member_email, client_pubkey, wallet_type, wallet_adr, verifyingChain, registered, verifyingContract, eula, profile, profile_data, signature) except ApplicationError as e: self.log.error('ApplicationError: {error}', error=e) self.leave('wamp.error', str(e)) return except Exception as e: raise e assert type(result) == dict assert 'timestamp' in result and type(result['timestamp']) == int and result['timestamp'] > 0 assert 'action' in result and result['action'] == 'onboard_member' assert 'vaction_oid' in result and type(result['vaction_oid']) == bytes and len(result['vaction_oid']) == 16 vaction_oid = uuid.UUID(bytes=result['vaction_oid']) self.log.info('On-boarding member - verification "{vaction_oid}" created', vaction_oid=vaction_oid)
def test_to_b58_string_valid(self, value): """ to_b58_string: test if it passes for all valid cases """ code = value['encoding']['code'] buffer = encode(bytes.fromhex(value['hex']), code) assert to_b58_string(buffer) == base58.b58encode(buffer).decode()
def test_hash(): data = hashlib.sha256(b'hello world').hexdigest() return multihash.encode(bytes.fromhex(data), 'sha2-256')
def test_encode_invalid_type(self, value): """ encode: raises TypeError when invalid type is given """ with pytest.raises(TypeError) as excinfo: encode(value, 0x11) assert 'must be a bytes object' in str(excinfo.value)
def get_s3_filename(self): return base58.b58encode( bytes(multihash.encode(self.body, multihash.SHA1)))