Exemplo n.º 1
0
def check_new_tx(tx: TX):
    if tx.height is not None:
        raise CheckWatchError('is not unconfirmed? {}'.format(tx))
    elif tx.message_type != C.MSG_BYTE:
        return
    elif tx.type == C.TX_CONCLUDE_CONTRACT:
        # 十分な署名が集まったら消す
        c_address, start_hash, c_storage = bjson.loads(tx.message)
        v = get_validator_object(c_address=c_address, stop_txhash=tx.hash)
        related_list = check_related_address(v.validators)
        if related_list:
            data = (time(), tx, related_list, c_address, start_hash, c_storage)
            watching_tx[tx.hash] = data
            NewInfo.put((C_Conclude, False, data))
    elif tx.type == C.TX_VALIDATOR_EDIT:
        # 十分な署名が集まったら消す
        c_address, new_address, flag, sig_diff = bjson.loads(tx.message)
        v = get_validator_object(c_address=c_address, stop_txhash=tx.hash)
        related_list = check_related_address(v.validators)
        if related_list:
            data = (time(), tx, related_list, c_address, new_address, flag,
                    sig_diff)
            watching_tx[tx.hash] = data
            NewInfo.put((C_Validator, False, data))
    else:
        pass
Exemplo n.º 2
0
Arquivo: builder.py Projeto: kmn/bc4py
 def put_unconfirmed(self, tx, outer_cur=None):
     assert tx.height is None, 'Not unconfirmed tx {}'.format(tx)
     if tx.type in (C.TX_POW_REWARD, C.TX_POS_REWARD):
         return  # It is Reword tx
     elif tx.hash in self.unconfirmed:
         logging.debug('Already unconfirmed tx. {}'.format(tx))
         return
     self.unconfirmed[tx.hash] = tx
     if tx.hash in self.chained_tx:
         logging.debug('Already chained tx. {}'.format(tx))
         return
     user_account.affect_new_tx(tx, outer_cur)
     NewInfo.put(obj=tx)
Exemplo n.º 3
0
    def run():
        global f_running
        f_running = True
        logging.info("Start emulators debug={}".format(f_debug))
        while f_running:
            try:
                data = NewInfo.get(channel='emulator', timeout=1)
                if not isinstance(data, tuple) or len(data) != 3:
                    continue
                cmd, is_public, data_list = data
                if cmd == C_RequestConclude:
                    # c_transfer tx is confirmed, create conclude tx
                    _time, start_tx, related_list, c_address, c_method, c_args = data_list
                    for e in emulators:
                        if e.c_address != c_address:
                            continue
                        # elif c_method == M_INIT:
                        #    pass
                        # elif c_method == M_UPDATE:
                        #    pass
                        else:
                            e.emulate(start_tx=start_tx, c_method=c_method, c_args=c_args, f_debug=f_debug)

                # elif cmd == C_Conclude:
                #    # sign already created conclude tx
                #    _time, tx, related_list, c_address, start_hash, c_storage = data_list
                else:
                    pass
            except NewInfo.empty:
                pass
            except Exception:
                logging.error("Emulator", exc_info=True)
Exemplo n.º 4
0
def new_insert_block(block, time_check=False):
    t = time.time()
    with global_lock:
        fixed_delay = time.time() - t
        try:
            # Check
            if time_check:
                check_block_time(block, fixed_delay)
            check_block(block)
            batch_sign_cashe(block.txs)
            for tx in block.txs:
                check_tx(tx=tx, include_block=block)
                if time_check:
                    check_tx_time(tx)
            # Recode
            builder.new_block(block)
            for tx in block.txs:
                user_account.affect_new_tx(tx)
            # Delete from sign-cashe
            delete_txhash_set = set()
            batched_blocks = builder.batch_apply()
            for del_block in batched_blocks:
                delete_txhash_set.update({tx.hash for tx in del_block.txs})
            delete_signed_cashe(delete_txhash_set)
            NewInfo.put(obj=block)
            logging.info("New block accepted {}Sec {}.".format(
                round(time.time() - t, 3), block))
            return True
        except BlockChainError as e:
            logging.warning("Reject new block by \"{}\"".format(e))
            delay = time.time(
            ) - builder.best_block.time - V.BLOCK_GENESIS_TIME
            if delay > 10800:  # 3hours
                logging.warning(
                    "{}Min before block inserted, too old on DB!".format(
                        delay // 60))
                P.F_NOW_BOOTING = True
            return False
        except BaseException as e:
            message = "New insert block error, \"{}\"".format(e)
            logging.warning(message, exc_info=True)
            add_failed_mark()
            return False
Exemplo n.º 5
0
def check_new_block(block: Block):
    for tx in block.txs:
        if tx.height is None:
            raise CheckWatchError('is unconfirmed? {}'.format(tx))
        elif tx.message_type != C.MSG_BYTE:
            continue
        elif tx.type == C.TX_TRANSFER:
            # ConcludeTXを作成するべきフォーマットのTXを見つける
            c_address, c_method, redeem_address, c_args = bjson.loads(
                tx.message)
            v = get_validator_object(c_address=c_address)
            related_list = check_related_address(v.validators)
            if related_list:
                data = (time(), tx, related_list, c_address, c_method,
                        redeem_address, c_args)
                watching_tx[tx.hash] = data
                NewInfo.put((C_RequestConclude, False, data))
        elif tx.type == C.TX_CONCLUDE_CONTRACT:
            if tx.hash in watching_tx:
                # try to delete c_transfer_tx and conclude_tx
                _time, _tx, _related_list, _c_address, start_hash, c_storage = watching_tx[
                    tx.hash]
                if start_hash in watching_tx:
                    del watching_tx[start_hash]
                del watching_tx[tx.hash]
            data = (time(), tx)
            NewInfo.put((C_FinishConclude, False, data))
        elif tx.type == C.TX_VALIDATOR_EDIT:
            if tx.hash in watching_tx:
                del watching_tx[tx.hash]
            data = (time(), tx)
            NewInfo.put((C_FinishValidator, False, data))
        else:
            pass
Exemplo n.º 6
0
def loop():
    logging.info("Watching contract start.")
    while not P.F_STOP and P.F_WATCH_CONTRACT:
        try:
            obj = NewInfo.get(channel='watch contract', timeout=2)
            if isinstance(obj, TX):
                check_new_tx(tx=obj)
            elif isinstance(obj, Block):
                check_new_block(block=obj)
            else:
                pass
        except NewInfo.empty:
            pass
        except CheckWatchError as e:
            logging.error(e)
        except Exception as e:
            logging.error(e, exc_info=True)
    logging.info("Close watching contract.")
Exemplo n.º 7
0
 def _loop():
     logging.info("start websocket loop.")
     while not P.F_STOP:
         try:
             data = NewInfo.get(channel='websocket', timeout=1)
             if isinstance(data, Block):
                 send_websocket_data(cmd=CMD_NEW_BLOCK,
                                     data=data.getinfo(),
                                     is_public_data=True)
             elif isinstance(data, TX):
                 send_websocket_data(cmd=CMD_NEW_TX,
                                     data=data.getinfo(),
                                     is_public_data=True)
             elif isinstance(data, tuple):
                 cmd, is_public, data_list = data
                 if cmd == C_Conclude:
                     _time, tx, related_list, c_address, start_hash, c_storage = data_list
                     send_data = OrderedDict()
                     send_data['c_address'] = c_address
                     send_data['hash'] = hexlify(tx.hash).decode()
                     send_data['time'] = _time
                     send_data['tx'] = tx.getinfo()
                     send_data['related'] = related_list
                     send_data['start_hash'] = hexlify(start_hash).decode()
                     send_data['c_storage'] = decode(c_storage)
                 elif cmd == C_Validator:
                     _time, tx, related_list, c_address, new_address, flag, sig_diff = data_list
                     send_data = OrderedDict()
                     send_data['c_address'] = c_address
                     send_data['hash'] = hexlify(tx.hash).decode()
                     send_data['time'] = _time
                     send_data['tx'] = tx.getinfo()
                     send_data['related'] = related_list
                     send_data['new_address'] = new_address
                     send_data['flag'] = flag
                     send_data['sig_diff'] = sig_diff
                 elif cmd == C_RequestConclude:
                     _time, tx, related_list, c_address, c_method, c_args = data_list
                     send_data = OrderedDict()
                     send_data['c_address'] = c_address
                     send_data['hash'] = hexlify(tx.hash).decode()
                     send_data['time'] = _time
                     send_data['tx'] = tx.getinfo()
                     send_data['related'] = related_list
                     send_data['c_method'] = c_method
                     send_data['c_args'] = decode(c_args)
                 elif cmd == C_FinishConclude or cmd == C_FinishValidator:
                     _time, tx = data_list
                     send_data = OrderedDict()
                     send_data['hash'] = hexlify(tx.hash).decode()
                     send_data['time'] = _time
                     send_data['tx'] = tx.getinfo()
                 else:
                     logging.warning("Not found cmd {}".format(cmd))
                     continue
                 send_websocket_data(cmd=cmd,
                                     data=send_data,
                                     is_public_data=is_public)
         except NewInfo.empty:
             pass
     logging.info("close websocket loop.")
Exemplo n.º 8
0
    def run():
        global f_running
        with lock:
            f_running = True

        # wait for booting_mode finish
        while P.F_NOW_BOOTING:
            sleep(1)

        logging.info("Start emulators, check unconfirmed.")
        unconfirmed_data = list()
        for tx in sorted(tx_builder.unconfirmed.values(), key=lambda x: x.time):
            if tx.type != C.TX_CONCLUDE_CONTRACT:
                continue
            try:
                c_address, start_hash, c_storage = bjson.loads(tx.message)
                for em in emulators:
                    if c_address == em.c_address:
                        break
                else:
                    continue
                start_tx = tx_builder.get_tx(txhash=start_hash)
                c_address2, c_method, redeem_address, c_args = bjson.loads(start_tx.message)
                if c_address != c_address2:
                    continue
                is_public = False
                data_list = (time(), start_tx, 'dummy', c_address, c_method, redeem_address, c_args)
                data = (C_RequestConclude, is_public, data_list)
                unconfirmed_data.append(data)
            except Exception:
                logging.debug("Failed check unconfirmed ConcludeTX,", exc_info=True)

        logging.info("Start listening NewInfo, need to emulate {} txs.".format(len(unconfirmed_data)))
        while f_running:
            try:
                if len(unconfirmed_data) > 0:
                    data = unconfirmed_data.pop(0)
                else:
                    data = NewInfo.get(channel='emulator', timeout=1)
                if not isinstance(data, tuple) or len(data) != 3:
                    continue
                cmd, is_public, data_list = data
                if cmd == C_RequestConclude:
                    # c_transfer tx is confirmed, create conclude tx
                    _time, start_tx, related_list, c_address, c_method, redeem_address, c_args = data_list
                    for e in emulators:
                        if e.c_address != c_address:
                            continue
                        elif c_method == M_INIT:
                            logging.warning("No work on init.")
                        # elif c_method == M_UPDATE:
                        #    pass
                        else:
                            if e.f_claim_gas:
                                gas_limit = 0
                                for address, coin_id, amount in start_tx.outputs:
                                    if address == c_address and coin_id == 0:
                                        gas_limit += amount
                            else:
                                gas_limit = None  # No limit on gas consumption, turing-complete
                            result, emulate_gas = execute(
                                c_address=c_address, genesis_block=genesis_block, start_tx=start_tx, c_method=c_method,
                                redeem_address=redeem_address, c_args=c_args, gas_limit=gas_limit, f_show_log=True)
                            claim_emulate_gas = emulate_gas if e.f_claim_gas else 0
                            broadcast(c_address=c_address, start_tx=start_tx, redeem_address=redeem_address,
                                      emulate_gas=claim_emulate_gas, result=result, f_debug=f_debug)

                # elif cmd == C_Conclude:
                #    # sign already created conclude tx
                #    _time, tx, related_list, c_address, start_hash, c_storage = data_list
                else:
                    pass
            except NewInfo.empty:
                pass
            except BlockChainError:
                logging.warning("Emulator", exc_info=True)
            except Exception:
                logging.error("Emulator", exc_info=True)