示例#1
0
    async def login(self, body, stream):
        if not StratumServer.config:
            StratumServer.config = get_config()
        if not StratumServer.config.mp:
            StratumServer.config.mp = await MiningPool.init_async()
        await StratumServer.block_checker()
        job = await StratumServer.config.mp.block_template()
        stream.peer = Peer(body['params'].get('login'))
        self.config.app_log.info(
            f'Connected to Miner: {stream.peer.to_json()}')
        StratumServer.inbound_streams[Miner.__name__][stream.peer] = stream
        if self.config.LatestBlock.block.index >= CHAIN.BLOCK_V5_FORK:
            job['job_id'] = job['job_id']
            job['blob'] = job['blob']
            result = {'id': job['blob'], 'job': job}
        else:
            job['job_id'] = job['blocktemplate_blob']
            job['blob'] = job['blocktemplate_blob']
            result = {'id': job['blocktemplate_blob'], 'job': job}

        rpc_data = {
            'id': body.get('id'),
            'method': body.get('method'),
            'jsonrpc': body.get('jsonrpc'),
            'result': result
        }
        await stream.write('{}\n'.format(json.dumps(rpc_data)).encode())
示例#2
0
 def get_service_providers(cls):
     config = get_config()
     if hasattr(config, 'network_service_providers'):
         service_providers = [
             ServiceProvider.from_dict(x)
             for x in config.network_service_providers
         ]
     else:
         service_providers = [
             ServiceProvider.from_dict({
                 'host': '3.225.228.97',
                 'port': 8000,
                 'identity': {
                     "username":
                     "",
                     "username_signature":
                     "MEQCIC7ADPLI3VPDNpQPaXAeB8gUk2LrvZDJIdEg9C12dj5PAiB61Te/sen1D++EJAcgnGLH4iq7HTZHv/FNByuvu4PrrA==",
                     "public_key":
                     "02a9aed3a4d69013246d24e25ded69855fbd590cb75b4a90fbfdc337111681feba"
                 }
             }),
         ]
     return OrderedDict(
         {x.identity.username_signature: x
          for x in service_providers})
示例#3
0
 def get_block_reward(cls, block_index=None):
     """Returns the reward matching a given block height, next block if None is provided"""
     if block_index is None:
         block_index = get_config().LatestBlock.block.index + 1
     index = block_index // 2100000
     reward = int(50.0 * 1e8 / 2**index) / 1e8
     return reward
示例#4
0
 def get_seed_gateways(cls):
     config = get_config()
     if hasattr(config, 'network_seed_gateways'):
         seed_gateways = [
             SeedGateway.from_dict(x) for x in config.network_seed_gateways
         ]
     else:
         seed_gateways = [
             SeedGateway.from_dict({
                 'host':
                 '18.214.218.185',
                 'port':
                 8000,
                 'identity': {
                     "username":
                     "",
                     "username_signature":
                     "MEQCIHONdT7i8K+ZTzv3PHyPAhYkaksoh6FxEJUmPLmXZqFPAiBHOnt1CjgMtNzCGdBk/0S/oikPzJVys32bgThxXtAbgQ==",
                     "public_key":
                     "03362203ee71bc15918a7992f3c76728fc4e45f4916d2c0311c37aad0f736b26b9"
                 },
                 "seed":
                 "MEUCIQCP+rF5R4sZ7pHJCBAWHxARLg9GN4dRw+/pobJ0MPmX3gIgX0RD4OxhSS9KPJTUonYI1Tr+ZI2N9uuoToZo1RGOs2M="
             }),
         ]
     return OrderedDict(
         {x.identity.username_signature: x
          for x in seed_gateways})
示例#5
0
 async def block_checker(cls):
     if not cls.config:
         cls.config = get_config()
     if cls.current_index != cls.config.LatestBlock.block.index:
         job = await cls.config.mp.block_template()
         if cls.config.LatestBlock.block.index >= CHAIN.BLOCK_V5_FORK:
             job['job_id'] = job['job_id']
             job['blob'] = job['blob']
             cls.current_index = cls.config.LatestBlock.block.index
             result = {'id': job['job_id'], 'job': job}
         else:
             job['job_id'] = job['blocktemplate_blob']
             job['blob'] = job['blocktemplate_blob']
             cls.current_index = cls.config.LatestBlock.block.index
             result = {'id': job['blocktemplate_blob'], 'job': job}
         rpc_data = {
             'id': 1,
             'method': 'login',
             'jsonrpc': 2.0,
             'result': result
         }
         for stream in StratumServer.inbound_streams[
                 Miner.__name__].values():
             try:
                 await stream.write('{}\n'.format(
                     json.dumps(rpc_data)).encode())
             except StreamClosedError:
                 await StratumServer.remove_peer(stream.peer)
             except Exception:
                 cls.config.app_log.warning(traceback.format_exc())
示例#6
0
 def __init__(self, public_key, address, txn_id, signature):
     # TODO: error, superclass init missing
     self.config = get_config()
     self.mongo = self.config.mongo
     self.public_key = public_key
     self.id = txn_id
     self.signature = signature
     self.address = address
示例#7
0
    async def connect(self, peer: Peer):
        try:
            stream = await super(NodeSocketClient, self).connect(peer)

            if not stream:
                return

            await self.write_params(stream, 'connect',
                                    {'peer': self.config.peer.to_dict()})

            stream.peer.token = str(uuid4())
            await self.write_params(stream, 'challenge', {
                'peer': self.config.peer.to_dict(),
                'token': stream.peer.token
            })

            await self.wait_for_data(stream)
        except StreamClosedError:
            get_config().app_log.error('Cannot connect to {}: {}'.format(
                peer.__class__.__name__, peer.to_json()))
示例#8
0
 def __init__(self,
              host=None,
              port=None,
              identity=None,
              seed=None,
              seed_gateway=None):
     self.host = host
     self.port = port
     self.identity = identity
     self.seed = seed
     self.seed_gateway = seed_gateway
     self.config = get_config()
     self.app_log = getLogger("tornado.application")
示例#9
0
 async def init_async(cls, blocks=None, partial=False):
     self = cls()
     self.config = get_config()
     self.mongo = self.config.mongo
     if isinstance(blocks, list):
         self.init_blocks = self.make_gen(blocks)
     elif not blocks:
         self.init_blocks = self.make_gen([])
     else:
         self.init_blocks = blocks
     self.partial = partial
     if not self.blocks:
         return  # allow nothing
     return self
示例#10
0
 async def init_async(
     cls,
     version=1,
     block_time=0,
     block_index=-1,
     prev_hash='',
     nonce:str='',
     transactions=None,
     block_hash='',
     merkle_root='',
     public_key='',
     signature='',
     special_min: bool=False,
     header= '',
     target: int=CHAIN.MAX_TARGET,
     special_target: int=CHAIN.MAX_TARGET
 ):
     self = cls()
     self.config = get_config()
     self.app_log = getLogger('tornado.application')
     self.version = version
     self.time = block_time
     self.index = block_index
     self.prev_hash = prev_hash
     self.nonce = nonce
     self.transactions = transactions or []
     # txn_hashes = self.get_transaction_hashes()
     # self.set_merkle_root(txn_hashes)
     self.merkle_root = merkle_root
     self.verify_merkle_root = ''
     self.hash = block_hash
     self.public_key = public_key
     self.signature = signature
     self.special_min = special_min
     self.target = target
     self.special_target = special_target
     if target==CHAIN.MAX_TARGET:
         # Same call as in new block check - but there's a circular reference here.
         latest_block = LatestBlock.block
         if not latest_block:
             self.target = CHAIN.MAX_TARGET
         else:
             if self.index >= CHAIN.FORK_10_MIN_BLOCK:
                 self.target = await CHAIN.get_target_10min(self.index, latest_block, self)
             else:
                 self.target = await CHAIN.get_target(self.index, latest_block, self)
         self.special_target = self.target
         # TODO: do we need recalc special target here if special min?
     self.header = header
     return self
示例#11
0
 def __init__(self):
     self.config = get_config()
     self.status = True
     self.tcp_server = TCPServerHealth()
     self.tcp_client = TCPClientHealth()
     self.consensus = ConsenusHealth()
     self.peer = PeerHealth()
     self.block_checker = BlockCheckerHealth()
     self.message_sender = MessageSenderHealth()
     self.block_inserter = BlockInserterHealth()
     self.pool_payer = PoolPayerHealth()
     self.cache_validator = CacheValidatorHealth()
     self.health_items = [
         self.consensus, self.tcp_server, self.tcp_client, self.peer,
         self.block_checker, self.message_sender, self.block_inserter,
         self.pool_payer, self.cache_validator
     ]
示例#12
0
 def __init__(
     self,
     txn_time='',
     rid='',
     transaction_signature='',
     relationship='',
     public_key='',
     dh_public_key='',
     fee=0.0,
     requester_rid='',
     requested_rid='',
     txn_hash='',
     inputs='',
     outputs='',
     coinbase=False,
     extra_blocks=None,
     seed_gateway_rid='',
     seed_rid=''
 ):
     self.app_log = getLogger("tornado.application")
     self.config = get_config()
     self.mongo = self.config.mongo
     self.time = txn_time
     self.rid = rid
     self.transaction_signature = transaction_signature
     self.relationship = relationship
     self.public_key = public_key
     self.dh_public_key = dh_public_key if dh_public_key else ''
     self.fee = float(fee)
     self.requester_rid = requester_rid if requester_rid else ''
     self.requested_rid = requested_rid if requested_rid else ''
     self.hash = txn_hash
     self.outputs = []
     self.extra_blocks = extra_blocks
     self.seed_gateway_rid = seed_gateway_rid,
     self.seed_rid = seed_rid
     for x in outputs:
         self.outputs.append(Output.from_dict(x))
     self.inputs = []
     for x in inputs:
         if 'signature' in x and 'public_key' in x and 'address' in x:
             self.inputs.append(ExternalInput.from_dict(x))
         else:
             self.inputs.append(Input.from_dict(x))
     self.coinbase = coinbase
示例#13
0
 async def login(self, body, stream):
     if not StratumServer.config:
         StratumServer.config = get_config()
     if not StratumServer.config.mp:
         StratumServer.config.mp = await MiningPool.init_async()
     job = await StratumServer.config.mp.block_template()
     stream.address = body['params'].get('login')
     StratumServer.inbound_streams[Miner.__name__][stream.address] = stream
     job['job_id'] = job['blocktemplate_blob']
     job['blob'] = job['blocktemplate_blob']
     result = {'id': job['blocktemplate_blob'], 'job': job}
     rpc_data = {
         'id': body.get('id'),
         'method': body.get('method'),
         'jsonrpc': body.get('jsonrpc'),
         'result': result
     }
     await stream.write('{}\n'.format(json.dumps(rpc_data)).encode())
示例#14
0
 async def block_checker(cls):
     if not cls.config:
         cls.config = get_config()
     if cls.current_index != cls.config.LatestBlock.block.index:
         job = await cls.config.mp.block_template()
         job['job_id'] = job['blocktemplate_blob']
         job['blob'] = job['blocktemplate_blob']
         cls.current_index = cls.config.LatestBlock.block.index
         result = {'id': job['blocktemplate_blob'], 'job': job}
         rpc_data = {
             'id': 1,
             'method': 'login',
             'jsonrpc': 2.0,
             'result': result
         }
         for address in StratumServer.inbound_streams[Miner.__name__]:
             await StratumServer.inbound_streams[
                 Miner.__name__
             ][address].write('{}\n'.format(json.dumps(rpc_data)).encode())
示例#15
0
 async def init_async(cls):
     self = cls()
     self.config = get_config()
     self.mongo = self.config.mongo
     self.app_log = getLogger("tornado.application")
     self.target_block_time = CHAIN.target_block_time(self.config.network)
     self.max_target = CHAIN.MAX_TARGET
     self.inbound = {}
     self.connected_ips = {}
     self.last_block_time = 0
     self.index = 0
     last_block = await self.config.BU.get_latest_block()
     if last_block:
         self.last_block_time = int(last_block['time'])
         self.index = last_block['index']
     self.last_refresh = 0
     self.block_factory = None
     await self.refresh()
     return self
示例#16
0
 def initialize(self):
     """Common init for every request"""
     origin = self.get_query_argument('origin', '*')
     if origin[-1] == '/':
         origin = origin[:-1]
     self.app_log = logging.getLogger("tornado.application")
     self.app_log.info(self._request_summary())
     self.config = get_config()
     self.yadacoin_vars = self.settings['yadacoin_vars']
     self.settings["page_title"] = self.settings["app_title"]
     self.set_header("Access-Control-Allow-Origin", origin)
     self.set_header('Access-Control-Allow-Credentials', "true")
     self.set_header('Access-Control-Allow-Methods', "GET, POST, OPTIONS")
     self.set_header('Access-Control-Expose-Headers', "Content-Type")
     self.set_header(
         'Access-Control-Allow-Headers',
         "Authorization, Content-Type, Depth, User-Agent, X-File-Size, X-Requested-With, X-Requested-By, If-Modified-Since, X-File-Name, Cache-Control"
     )
     self.set_header('Access-Control-Max-Age', 600)
     self.jwt = {}
示例#17
0
    async def init_async(cls,
                         debug=False,
                         prevent_genesis=False,
                         target=None,
                         special_target=None):
        self = cls()
        self.app_log = logging.getLogger("tornado.application")
        self.debug = debug
        self.config = get_config()
        self.mongo = self.config.mongo
        self.prevent_genesis = prevent_genesis
        self.target = target
        self.special_target = special_target
        self.syncing = False

        if self.config.LatestBlock.block:
            self.latest_block = self.config.LatestBlock.block
        else:
            if not self.prevent_genesis:
                await self.config.BU.insert_genesis()
        return self
示例#18
0
 def __init__(self,
              host=None,
              port=None,
              identity=None,
              seed=None,
              seed_gateway=None,
              http_host=None,
              http_port=None,
              secure=None,
              protocol_version=3):
     self.host = host
     self.port = port
     self.identity = identity
     self.seed = seed
     self.seed_gateway = seed_gateway
     self.http_host = http_host
     self.http_port = http_port
     self.secure = secure
     self.config = get_config()
     self.app_log = getLogger("tornado.application")
     self.protocol_version = protocol_version
     self.authenticated = False
示例#19
0
 def get_groups(cls):
     config = get_config()
     if hasattr(config, 'network_groups'):
         groups = [Group.from_dict(x) for x in config.network_groups]
     else:
         groups = [
             Group.from_dict({
                 'host': None,
                 'port': None,
                 'identity': {
                     'username':
                     '******',
                     'username_signature':
                     'MEUCIQDIlC+SpeLwUI4fzV1mkEsJCG6HIvBvazHuMMNGuVKi+gIgV8r1cexwDHM3RFGkP9bURi+RmcybaKHUcco1Qu0wvxw=',
                     'public_key':
                     '036f99ba2238167d9726af27168384d5fe00ef96b928427f3b931ed6a695aaabff',
                     'wif':
                     'KydUVG4w2ZSQkg6DAZ4UCEbfZz9Tg4PsjJFnvHwFsfmRkqXAHN8W'
                 }
             })
         ]
     return OrderedDict({x.identity.username_signature: x for x in groups})
示例#20
0
    def create_upnp_mapping(cls, config):
        from miniupnpc import UPnP
        config = get_config()
        try:
            u = UPnP(None, None, 200, 0)
            u.discover()
            config.igd = u.selectigd()
        except:
            config.igd = ""
        if config.use_pnp:
            import socket
            # deploy as an eventlet WSGI server
            try:
                server_port = config.peer_port
                eport = server_port
                r = u.getspecificportmapping(eport, 'TCP')
                if r:
                    u.deleteportmapping(eport, 'TCP')
                u.addportmapping(eport, 'TCP', u.lanaddr, server_port,
                                 'UPnP YadaCoin Serve port %u' % eport, '')
                config.peer_host = u.externalipaddress()

                if 'web' in config.modes:
                    server_port = config.serve_port
                    eport = server_port
                    r = u.getspecificportmapping(eport, 'TCP')
                    if r:
                        u.deleteportmapping(eport, 'TCP')
                    u.addportmapping(eport, 'TCP', u.lanaddr, server_port,
                                     'UPnP YadaCoin Serve port %u' % eport, '')
            except Exception as e:
                print(e)
                config.serve_host = config.serve_host
                config.serve_port = config.serve_port
                config.peer_host = config.peer_host
                config.peer_port = config.peer_port
                print('UPnP failed: you must forward and/or whitelist port',
                      config.peer_port)
示例#21
0
 def get_seeds(cls):
     config = get_config()
     if hasattr(config, 'network_seeds'):
         seeds = [Seed.from_dict(x) for x in config.network_seeds]
     else:
         seeds = [
             Seed.from_dict({
                 'host':
                 '34.237.46.10',
                 'port':
                 8000,
                 'identity': {
                     "username":
                     "",
                     "username_signature":
                     "MEUCIQCP+rF5R4sZ7pHJCBAWHxARLg9GN4dRw+/pobJ0MPmX3gIgX0RD4OxhSS9KPJTUonYI1Tr+ZI2N9uuoToZo1RGOs2M=",
                     "public_key":
                     "02fa9550f57055c96c7ce4c6c9cd1411856beba5c7d5a07417e980a39aa03da3dc"
                 },
                 "seed_gateway":
                 "MEQCIHONdT7i8K+ZTzv3PHyPAhYkaksoh6FxEJUmPLmXZqFPAiBHOnt1CjgMtNzCGdBk/0S/oikPzJVys32bgThxXtAbgQ=="
             }),
         ]
     return OrderedDict({x.identity.username_signature: x for x in seeds})
示例#22
0
 def __init__(self):
     self.config = get_config()
     self.mongo = self.config.mongo
     self.latest_block = None
     self.app_log = getLogger('tornado.application')
示例#23
0
    async def generate(
        cls,
        transactions=None,
        public_key=None,
        private_key=None,
        force_version=None,
        index=0,
        force_time=None,
        prev_hash=None,
        nonce=None,
        target=CHAIN.MAX_TARGET
    ):
        config = get_config()
        app_log = getLogger("tornado.application")
        if force_version is None:
            version = CHAIN.get_version_for_height(index)
        else:
            version = force_version
        if force_time:
            xtime = str(int(force_time))
        else:
            xtime = str(int(time.time()))
        index = int(index)
        if index == 0:
            prev_hash = ''
        elif prev_hash is None and index != 0:
            prev_hash = LatestBlock.block.hash
        transactions = transactions or []

        transaction_objs = []
        fee_sum = 0.0
        used_sigs = []
        used_inputs = {}
        for txn in transactions:
            try:
                if isinstance(txn, Transaction):
                    transaction_obj = txn
                else:
                    transaction_obj = Transaction.from_dict(txn)

                if transaction_obj.transaction_signature in used_sigs:
                    print('duplicate transaction found and removed')
                    continue

                await transaction_obj.verify()
                used_sigs.append(transaction_obj.transaction_signature)
            except:
                raise InvalidTransactionException("invalid transactions")
            try:
                if int(index) > CHAIN.CHECK_TIME_FROM and (int(transaction_obj.time) > int(xtime) + CHAIN.TIME_TOLERANCE):
                    config.mongo.db.miner_transactions.remove({'id': transaction_obj.transaction_signature}, multi=True)
                    app_log.debug("Block embeds txn too far in the future {} {}".format(xtime, transaction_obj.time))
                    continue
                
                if transaction_obj.inputs:
                    failed = False
                    used_ids_in_this_txn = []
                    for x in transaction_obj.inputs:
                        if config.BU.is_input_spent(x.id, transaction_obj.public_key):
                            failed = True
                        if x.id in used_ids_in_this_txn:
                            failed = True
                        if (x.id, transaction_obj.public_key) in used_inputs:
                            failed = True
                        used_inputs[(x.id, transaction_obj.public_key)] = transaction_obj
                        used_ids_in_this_txn.append(x.id)
                    if failed:
                        continue

                transaction_objs.append(transaction_obj)

                fee_sum += float(transaction_obj.fee)
            except Exception as e:
                await config.mongo.async_db.miner_transactions.delete_many({'id': transaction_obj.transaction_signature})
                config.app_log.debug('Exception {}'.format(e))
                continue

        block_reward = CHAIN.get_block_reward(index)
        coinbase_txn = await Transaction.generate(
            public_key=public_key,
            private_key=private_key,
            outputs=[{
                'value': block_reward + float(fee_sum),
                'to': str(P2PKHBitcoinAddress.from_pubkey(bytes.fromhex(public_key)))
            }],
            coinbase=True
        )
        transaction_objs.append(coinbase_txn)

        transactions = transaction_objs
        block = await cls.init_async(
            version=version,
            block_time=xtime,
            block_index=index,
            prev_hash=prev_hash,
            transactions=transactions,
            public_key=public_key,
            target=target
        )
        txn_hashes = block.get_transaction_hashes()
        block.set_merkle_root(txn_hashes)
        block.target = target
        block.header = block.generate_header()
        if nonce:
            block.nonce = str(nonce)
            block.hash = block.generate_hash_from_header(
                block.index,
                block.header,
                str(block.nonce)
            )
            block.signature = TU.generate_signature(block.hash, private_key)
        return block
示例#24
0
 def __init__(self):
     super(NodeSocketClient, self).__init__()
     self.config = get_config()
示例#25
0
 def __init__(self):
     super(NodeSocketServer, self).__init__()
     self.config = get_config()
示例#26
0
 def __init__(self):
     super(NodeRPC, self).__init__()
     self.config = get_config()
示例#27
0
 def __init__(self):
     self.config = get_config()
示例#28
0
    async def test_block(self,
                         block,
                         extra_blocks=[],
                         simulate_last_block=None):
        try:
            block.verify()
        except Exception as e:
            self.config.app_log.warning(
                "Integrate block error 1: {}".format(e))
            return False

        async def get_txns(txns):
            for x in txns:
                yield x

        async def get_inputs(inputs):
            for x in inputs:
                yield x

        if block.index == 0:
            return True

        if simulate_last_block:
            last_block = simulate_last_block
        else:
            last_block_data = await self.config.mongo.async_db.blocks.find_one(
                {'index': block.index - 1})
            if last_block_data:
                last_block = await Block.from_dict(last_block_data)
            else:
                return False

        if block.index >= CHAIN.FORK_10_MIN_BLOCK:
            target = await CHAIN.get_target_10min(block.index, last_block,
                                                  block, extra_blocks)
        else:
            target = await CHAIN.get_target(block.index, last_block, block,
                                            extra_blocks)

        delta_t = int(time()) - int(last_block.time)
        special_target = CHAIN.special_target(block.index, block.target,
                                              delta_t,
                                              get_config().network)

        if block.index >= 35200 and delta_t < 600 and block.special_min:
            return False

        used_inputs = {}
        i = 0
        async for transaction in get_txns(block.transactions):
            if extra_blocks:
                transaction.extra_blocks = extra_blocks
            self.config.app_log.warning('verifying txn: {} block: {}'.format(
                i, block.index))
            i += 1
            try:
                await transaction.verify()
            except InvalidTransactionException as e:
                self.config.app_log.warning(e)
                return False
            except InvalidTransactionSignatureException as e:
                self.config.app_log.warning(e)
                return False
            except MissingInputTransactionException as e:
                self.config.app_log.warning(e)
                return False
            except NotEnoughMoneyException as e:
                self.config.app_log.warning(e)
                return False
            except Exception as e:
                self.config.app_log.warning(e)
                return False

            if transaction.inputs:
                failed = False
                used_ids_in_this_txn = []
                async for x in get_inputs(transaction.inputs):
                    txn = self.config.BU.get_transaction_by_id(x.id,
                                                               instance=True)
                    if not txn:
                        txn = await transaction.find_in_extra_blocks(x)
                        if not txn:
                            failed = True
                    if self.config.BU.is_input_spent(x.id,
                                                     transaction.public_key,
                                                     from_index=block.index):
                        failed = True
                    if x.id in used_ids_in_this_txn:
                        failed = True
                    if (x.id, transaction.public_key) in used_inputs:
                        failed = True
                    used_inputs[(x.id, transaction.public_key)] = transaction
                    used_ids_in_this_txn.append(x.id)
                if failed and block.index >= CHAIN.CHECK_DOUBLE_SPEND_FROM:
                    return False
                elif failed and block.index < CHAIN.CHECK_DOUBLE_SPEND_FROM:
                    continue

        if block.index >= 35200 and delta_t < 600 and block.special_min:
            self.config.app_log.warning(
                f'Failed: {block.index} >= {35200} and {delta_t} < {600} and {block.special_min}'
            )
            return False

        if int(block.index) > CHAIN.CHECK_TIME_FROM and int(block.time) < int(
                last_block.time):
            self.config.app_log.warning(
                f'Failed: {int(block.index)} > {CHAIN.CHECK_TIME_FROM} and {int(block.time)} < {int(last_block.time)}'
            )
            return False

        if last_block.index != (block.index -
                                1) or last_block.hash != block.prev_hash:
            self.config.app_log.warning(
                f'Failed: {last_block.index} != {(block.index - 1)} or {last_block.hash} != {block.prev_hash}'
            )
            return False

        if int(block.index) > CHAIN.CHECK_TIME_FROM and (
                int(block.time) <
            (int(last_block.time) + 600)) and block.special_min:
            self.config.app_log.warning(
                f'Failed: {int(block.index)} > {CHAIN.CHECK_TIME_FROM} and ({int(block.time)} < ({int(last_block.time)} + {600})) and {block.special_min}'
            )
            return False

        target_block_time = CHAIN.target_block_time(self.config.network)

        checks_passed = False
        if (block.index >= CHAIN.BLOCK_V5_FORK) and int(
                block.little_hash(), 16) < target:
            self.config.app_log.warning('5')
            checks_passed = True
        elif (int(block.hash, 16) < target):
            self.config.app_log.warning('6')
            checks_passed = True
        elif (block.special_min and int(block.hash, 16) < special_target):
            self.config.app_log.warning('7')
            checks_passed = True
        elif (block.special_min and block.index < 35200):
            self.config.app_log.warning('8')
            checks_passed = True
        elif (block.index >= 35200 and block.index < 38600
              and block.special_min and
              (int(block.time) - int(last_block.time)) > target_block_time):
            self.config.app_log.warning('9')
            checks_passed = True
        else:
            self.config.app_log.warning(
                "Integrate block error - index and time error")

        if not checks_passed:
            return False

        return True
示例#29
0
    async def generate(cls,
                       bulletin_secret='',
                       username='',
                       value=0,
                       fee=0.0,
                       rid='',
                       requester_rid='',
                       requested_rid='',
                       public_key='',
                       dh_public_key='',
                       private_key='',
                       dh_private_key='',
                       to='',
                       inputs='',
                       outputs='',
                       coinbase=False,
                       chattext=None,
                       signin=None,
                       relationship='',
                       no_relationship=False,
                       exact_match=False):
        cls_inst = cls()
        cls_inst.config = get_config()
        cls_inst.mongo = cls_inst.config.mongo
        cls_inst.app_log = getLogger('tornado.application')
        cls_inst.bulletin_secret = bulletin_secret
        cls_inst.username = username
        cls_inst.rid = rid
        cls_inst.requester_rid = requester_rid
        cls_inst.requested_rid = requested_rid
        cls_inst.public_key = public_key
        cls_inst.dh_public_key = dh_public_key
        cls_inst.private_key = private_key
        cls_inst.value = value
        cls_inst.fee = float(fee)
        cls_inst.dh_private_key = dh_private_key
        cls_inst.to = to
        cls_inst.time = str(int(time.time()))
        cls_inst.outputs = []
        cls_inst.relationship = relationship
        cls_inst.no_relationship = no_relationship
        cls_inst.exact_match = exact_match
        for x in outputs:
            cls_inst.outputs.append(Output.from_dict(x))
        cls_inst.inputs = []
        for x in inputs:
            if 'signature' in x and 'public_key' in x and 'address' in x:
                cls_inst.inputs.append(ExternalInput.from_dict(x))
            else:
                cls_inst.inputs.append(Input.from_dict(x))
        cls_inst.coinbase = coinbase
        cls_inst.chattext = chattext
        cls_inst.signin = signin
        await cls_inst.do_money()

        inputs_concat = ''.join([
            x.id for x in sorted(cls_inst.inputs, key=lambda x: x.id.lower())
        ])
        outputs_concat = cls_inst.get_output_hashes()
        if bulletin_secret or rid:
            if not cls_inst.rid:
                cls_inst.rid = cls_inst.generate_rid()
            if cls_inst.chattext:
                cls_inst.relationship = json.dumps(
                    {"chatText": cls_inst.chattext})
                cls_inst.encrypted_relationship = cls_inst.config.cipher.encrypt(
                    cls_inst.relationship)
            elif cls_inst.signin:
                for shared_secret in cls_inst.config.GU.get_shared_secrets_by_rid(
                        cls_inst.rid):
                    cls_inst.relationship = SignIn(cls_inst.signin)
                    cls_inst.cipher = Crypt(shared_secret.hex(), shared=True)
                    cls_inst.encrypted_relationship = cls_inst.cipher.shared_encrypt(
                        cls_inst.relationship.to_json())
                    break
            elif cls_inst.relationship:
                cls_inst.encrypted_relationship = cls_inst.relationship
            elif cls_inst.no_relationship:
                cls_inst.encrypted_relationship = ''
            else:
                if not cls_inst.dh_public_key or not cls_inst.dh_private_key:
                    a = os.urandom(32).decode('latin1')
                    cls_inst.dh_public_key = scalarmult_base(a).encode(
                        'latin1').hex()
                    cls_inst.dh_private_key = a.encode().hex()
                cls_inst.relationship = cls_inst.generate_relationship()
                if not private_key:
                    raise Exception('missing private key')
                cls_inst.encrypted_relationship = cls_inst.config.cipher.encrypt(
                    cls_inst.relationship.to_json().encode())
        else:
            cls_inst.rid = ''
            cls_inst.encrypted_relationship = ''

        cls_inst.header = (cls_inst.public_key + cls_inst.time +
                           cls_inst.dh_public_key + cls_inst.rid +
                           cls_inst.encrypted_relationship +
                           "{0:.8f}".format(cls_inst.fee) +
                           cls_inst.requester_rid + cls_inst.requested_rid +
                           inputs_concat + outputs_concat)
        cls_inst.hash = hashlib.sha256(
            cls_inst.header.encode('utf-8')).digest().hex()
        if cls_inst.private_key:
            cls_inst.transaction_signature = TU.generate_signature_with_private_key(
                private_key, cls_inst.hash)
        else:
            cls_inst.transaction_signature = ''
        return cls(cls_inst.time,
                   cls_inst.rid,
                   cls_inst.transaction_signature,
                   cls_inst.encrypted_relationship,
                   cls_inst.public_key,
                   cls_inst.dh_public_key,
                   float(cls_inst.fee),
                   cls_inst.requester_rid,
                   cls_inst.requested_rid,
                   cls_inst.hash,
                   inputs=[x.to_dict() for x in cls_inst.inputs],
                   outputs=[x.to_dict() for x in cls_inst.outputs],
                   coinbase=cls_inst.coinbase)
示例#30
0
    def __init__(self):
        self.config = get_config()
        self.client = MongoClient(self.config.mongodb_host)
        self.db = self.client[self.config.database]
        self.site_db = self.client[self.config.site_database]
        try:
            # test connection
            self.db.yadacoin.find_one()
        except:
            if hasattr(self.config, 'mongod_path'):
                os.system('sudo {} --syslog --fork'.format(
                    self.config.mongod_path))
            else:
                os.system('sudo mongod --syslog --fork')

        __id = IndexModel([("id", ASCENDING)], name="__id", unique=True)
        __hash = IndexModel([("hash", ASCENDING)], name="__hash")
        __index = IndexModel([("index", ASCENDING)], name="__index")
        __to = IndexModel([("transactions.outputs.to", ASCENDING)],
                          name="__to")
        __txn_id = IndexModel([("transactions.id", ASCENDING)],
                              name="__txn_id")
        __txn_inputs_id = IndexModel([("transactions.inputs.id", ASCENDING)],
                                     name="__txn_inputs_id")
        __txn_public_key = IndexModel([("transactions.public_key", ASCENDING)],
                                      name="__txn_public_key")
        __txn_inputs_public_key = IndexModel(
            [("transactions.inputs.public_key", ASCENDING)],
            name="__txn_inputs_public_key")
        __txn_inputs_address = IndexModel(
            [("transactions.inputs.address", ASCENDING)],
            name="__txn_inputs_address")
        __txn_public_key_inputs_public_key_address = IndexModel(
            [
                ("transactions.public_key", ASCENDING),
                ("transactions.inputs.public_key", ASCENDING),
                ("transactions.inputs.address", ASCENDING),
            ],
            name="__txn_public_key_inputs_public_key_address")

        try:
            self.db.blocks.create_indexes([
                __hash, __index, __id, __to, __txn_id, __txn_inputs_id,
                __txn_public_key, __txn_inputs_public_key,
                __txn_inputs_address,
                __txn_public_key_inputs_public_key_address
            ])
        except:
            pass

        __id = IndexModel([("id", ASCENDING)], name="__id")
        __height = IndexModel([("height", ASCENDING)], name="__height")
        try:
            self.db.unspent_cache.create_indexes([__id, __height])
        except:
            pass

        __id = IndexModel([("id", ASCENDING)], name="__id")
        __index = IndexModel([("index", ASCENDING)], name="__index")
        __block_hash = IndexModel([("block.hash", ASCENDING)],
                                  name="__block_hash")
        __block_prevHash_index_version = IndexModel(
            [("block.prevHash", ASCENDING), ("block.index", ASCENDING),
             ("block.version", ASCENDING)],
            name="__block_prevHash_index_version")
        try:
            self.db.consensus.create_indexes(
                [__id, __index, __block_hash, __block_prevHash_index_version])
        except:
            pass

        __address = IndexModel([("address", ASCENDING)], name="__address")
        __index = IndexModel([("index", ASCENDING)], name="__index")
        __hash = IndexModel([("hash", ASCENDING)], name="__hash")
        try:
            self.db.shares.create_indexes([__address, __index, __hash])
        except:
            pass

        __txn_id = IndexModel([("txn.id", ASCENDING)], name="__txn_id")
        try:
            self.db.transactions_by_rid_cache.create_indexes([__txn_id])
        except:
            pass

        # TODO: add indexes for peers

        # See https://motor.readthedocs.io/en/stable/tutorial-tornado.html
        self.async_client = MotorClient(self.config.mongodb_host)
        self.async_db = self.async_client[self.config.database]
        self.async_site_db = self.async_client[self.config.site_database]