Ejemplo 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
Ejemplo n.º 2
0
Archivo: builder.py Proyecto: kmn/bc4py
 def read_contract_iter(self, c_address, start_idx=None):
     f_batch = self.is_batch_thread()
     batch_copy = self.batch['_contract'].copy() if self.batch else dict()
     b_c_address = c_address.encode()
     # caution: iterator/RangeIter's result include start and stop, need to add 1.
     start = b_c_address + ((start_idx+1).to_bytes(8, ITER_ORDER) if start_idx else b'\x00'*8)
     stop = b_c_address + b'\xff'*8
     if is_plyvel:
         contract_iter = self._contract.iterator(start=start, stop=stop)
     else:
         contract_iter = self._contract.RangeIter(key_from=start, key_to=stop)
     for k, v in contract_iter:
         k, v = bytes(k), bytes(v)
         # KEY: [c_address 40s]-[index uint8]
         # VALUE: [start_hash 32s]-[finish_hash 32s]-[bjson(c_method, c_args, c_storage)]
         # c_address, index, start_hash, finish_hash, message
         if f_batch and k in batch_copy and start <= k <= stop:
             v = batch_copy[k]
             del batch_copy[k]
         dummy, index = struct_construct_key.unpack(k)
         start_hash, finish_hash, raw_message = v[0:32], v[32:64], v[64:]
         message = bjson.loads(raw_message)
         yield index, start_hash, finish_hash, message
     if f_batch:
         for k, v in sorted(batch_copy.items(), key=lambda x: x[0]):
             if k.startswith(b_c_address) and start <= k <= stop:
                 dummy, index = struct_construct_key.unpack(k)
                 start_hash, finish_hash, raw_message = v[0:32], v[32:64], v[64:]
                 message = bjson.loads(raw_message)
                 yield index, start_hash, finish_hash, message
Ejemplo n.º 3
0
Archivo: builder.py Proyecto: kmn/bc4py
 def read_coins_iter(self, coin_id):
     f_batch = self.is_batch_thread()
     batch_copy = self.batch['_coins'].copy() if self.batch else dict()
     b_coin_id = coin_id.to_bytes(4, ITER_ORDER)
     start = b_coin_id + b'\x00'*4
     stop = b_coin_id + b'\xff'*4
     if is_plyvel:
         coins_iter = self._coins.iterator(start=start, stop=stop)
     else:
         coins_iter = self._coins.RangeIter(key_from=start, key_to=stop)
     for k, v in coins_iter:
         k, v = bytes(k), bytes(v)
         # coin_id, index, txhash
         if f_batch and k in batch_copy and start <= k <= stop:
             v = batch_copy[k]
             del batch_copy[k]
         dummy, index = struct_coins.unpack(k)
         txhash, (params, setting) = v[:32], bjson.loads(v[32:])
         yield index, txhash, params, setting
     if f_batch:
         for k, v in sorted(batch_copy.items(), key=lambda x: x[0]):
             if k.startswith(b_coin_id) and start <= k <= stop:
                 dummy, index = struct_coins.unpack(k)
                 txhash, (params, setting) = v[:32], bjson.loads(v[32:])
                 yield index, txhash, params, setting
Ejemplo n.º 4
0
 def read_contract_iter(self, c_address):
     f_batch = self.is_batch_thread()
     batch_copy = self.batch['_contract'].copy() if self.batch else dict()
     b_c_address = c_address.encode()
     start = b_c_address + b'\x00'*4
     stop = b_c_address + b'\xff'*4
     if is_plyvel:
         contract_iter = self._contract.iterator(start=start, stop=stop)
     else:
         contract_iter = self._contract.RangeIter(key_from=start, key_to=stop)
     for k, v in contract_iter:
         k, v = bytes(k), bytes(v)
         # KEY: [c_address 40s]-[index uint4]
         # VALUE: [start_hash 32s]-[finish_hash 32s]-[len uint4]-[bjson(c_method, c_args, c_storage)]
         # c_address, index, start_hash, finish_hash, message
         if f_batch and k in batch_copy:
             v = batch_copy[k]
             del batch_copy[k]
         dummy, index = struct_construct_key.unpack(k)
         start_hash, finish_hash, raw_message = v[0:32], v[32:64], v[64:]
         message = bjson.loads(raw_message)
         yield index, start_hash, finish_hash, message
     if f_batch:
         for k, v in sorted(batch_copy.items(), key=lambda x: x[0]):
             if k.startswith(b_c_address):
                 dummy, index = struct_construct_key.unpack(k)
                 start_hash, finish_hash, raw_message = v[0:32], v[32:64], v[64:]
                 message = bjson.loads(raw_message)
                 yield index, start_hash, finish_hash, message
Ejemplo n.º 5
0
def load_boot_file():
    normal_path = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                               'boot.dat')
    extra_path = os.path.join(V.DB_HOME_DIR, 'boot.dat')
    if os.path.exists(normal_path):
        with open(normal_path, mode='br') as fp:
            data = bjson.loads(
                b64decode(fp.read().replace(b'\n', b'').replace(b'\r', b'')))
    elif os.path.exists(extra_path):
        with open(extra_path, mode='br') as fp:
            data = bjson.loads(
                b64decode(fp.read().replace(b'\n', b'').replace(b'\r', b'')))
    else:
        raise FileNotFoundError('Cannot find boot.dat "{}" or "{}" ?'.format(
            normal_path, extra_path))
    genesis_block = Block(binary=data['block'])
    genesis_block.flag = C.BLOCK_GENESIS
    genesis_block.height = 0
    for b_tx in data['txs']:
        tx = TX(binary=b_tx)
        tx.height = 0
        genesis_block.txs.append(tx)
    connections = data.get('connections', list())
    network_ver = data['network_ver']
    return genesis_block, network_ver, connections
Ejemplo n.º 6
0
def get_contract_history_iter(c_address, best_block=None, best_chain=None):
    # DataBaseより
    last_index = 0
    for dummy, index, start_hash, finish_hash in builder.db.read_contract_iter(c_address):
        yield index, start_hash, finish_hash, None, False
        last_index += 1
    # Memoryより
    best_chain = best_chain or _get_best_chain_all(best_block)
    for block in reversed(best_chain):
        for tx in block.txs:
            if tx.type == C.TX_CREATE_CONTRACT:
                c_address2, c_bin, c_cs = bjson.loads(tx.message)
                if c_address == c_address2:
                    yield 0, tx.hash, b'\x00'*32, tx.height, True
                    last_index += 1
            elif tx.type == C.TX_START_CONTRACT:
                c_address2, c_method, c_args, c_redeem = bjson.loads(tx.message)
                if c_address != c_address2:
                    continue
                for finish_tx in block.txs:
                    if finish_tx.type != C.TX_FINISH_CONTRACT:
                        continue
                    dummy0, start_hash, dummy1 = bjson.loads(finish_tx.message)
                    if start_hash == tx.hash:
                        yield last_index, start_hash, finish_tx.hash, tx.height, True
                        last_index += 1
                        break
    # Unconfirmedより
    if best_block is None:
        validator_cks, required_num = get_validator_info()
        for tx in sorted(tx_builder.unconfirmed.values(), key=lambda x: x.time):
            if tx.type == C.TX_CREATE_CONTRACT:
                yield 0, tx.hash, b'\x00'*32, None, True
                last_index += 1
            if tx.type == C.TX_START_CONTRACT:
                c_address2, c_method, c_args, c_redeem = bjson.loads(tx.message)
                if c_address != c_address2:
                    continue
                for finish_tx in tx_builder.unconfirmed.values():
                    if len(finish_tx.signature) < required_num:
                        continue
                    elif finish_tx.type != C.TX_FINISH_CONTRACT:
                        continue
                    dummy0, start_hash, dummy1 = bjson.loads(finish_tx.message)
                    if start_hash == tx.hash:
                        yield last_index, start_hash, finish_tx.hash, None, True
                        last_index += 1
                        break
Ejemplo n.º 7
0
        def processing():
            self.threadid = get_ident()
            while not self.f_stop:
                user = msg_body = None
                try:
                    user, msg_body = processing_que.get(timeout=1)
                    item = bjson.loads(msg_body)

                    if item['type'] == T_REQUEST:
                        if item['cmd'] == ClientCmd.BROADCAST:
                            # broadcastはCheckを含む為に別スレッド
                            broadcast_que.put((user, item))
                        else:
                            self.type_request(user=user, item=item)
                    elif item['type'] == T_RESPONSE:
                        self.type_response(user=user, item=item)
                    elif item['type'] == T_ACK:
                        self.type_ack(user=user, item=item)
                    else:
                        logging.debug("Unknown type {}".format(item['type']))
                except bjson.BJsonBaseError:
                    self.p2p.remove_connection(user)
                    logging.debug("BJsonBaseError", exc_info=Debug.P_EXCEPTION)
                except queue.Empty:
                    pass
                except Exception as e:
                    logging.debug("Processing error, ({}, {}, {})".format(
                        user.name, msg_body, e),
                                  exc_info=Debug.P_EXCEPTION)
            self.f_finish = True
            self.f_running = False
            logging.info("Close processing.")
Ejemplo n.º 8
0
def set_blockchain_params(genesis_block):
    assert 'spawn' in multiprocessing.get_all_start_methods(), 'Not found spawn method.'
    setting_tx = genesis_block.txs[0]
    params = bjson.loads(setting_tx.message)
    V.BLOCK_GENESIS_HASH = genesis_block.hash
    V.BLOCK_PREFIX = params.get('prefix')
    V.BLOCK_CONTRACT_PREFIX = params.get('contract_prefix')
    V.BLOCK_GENESIS_TIME = params.get('genesis_time')
    V.BLOCK_ALL_SUPPLY = params.get('all_supply')
    V.BLOCK_TIME_SPAN = params.get('block_span')
    V.BLOCK_REWARD = params.get('block_reward')
    V.CONTRACT_VALIDATOR_ADDRESS = params.get('validator_address')
    V.COIN_DIGIT = params.get('digit_number')
    V.COIN_MINIMUM_PRICE = params.get('minimum_price')
    V.CONTRACT_MINIMUM_AMOUNT = params.get('contract_minimum_amount')
    consensus = params.get('consensus')
    if isinstance(consensus, dict):
        V.BLOCK_CONSENSUS = consensus
        V.BLOCK_BASE_CONSENSUS = min(consensus.keys())
    else:
        # TODO: remove after test
        pow_ratio = params.get('pow_ratio')
        V.BLOCK_CONSENSUS = {C.BLOCK_YES_POW: pow_ratio, C.BLOCK_POS: 100 - pow_ratio}
        V.BLOCK_BASE_CONSENSUS = C.BLOCK_YES_POW
    GompertzCurve.setup_params()
Ejemplo n.º 9
0
        def processing():
            que = self.p2p.core_que.create()
            while not self.f_stop:
                user = msg_body = None
                try:
                    user, msg_body = que.get(timeout=1)
                    item = bjson.loads(msg_body)

                    if item['type'] == T_REQUEST:
                        self.type_request(user=user, item=item)
                    elif item['type'] == T_RESPONSE:
                        self.type_response(user=user, item=item)
                    elif item['type'] == T_ACK:
                        self.type_ack(user=user, item=item)
                    else:
                        logging.debug("Unknown type {}".format(item['type']))
                except bjson.BJsonBaseError:
                    self.p2p.remove_connection(user)
                    logging.debug("BJsonBaseError", exc_info=Debug.P_EXCEPTION)
                except queue.Empty:
                    pass
                except Exception as e:
                    logging.debug("Processing error, ({}, {}, {})"
                                  .format(user.name, msg_body, e), exc_info=Debug.P_EXCEPTION)
            self.f_finish = True
            self.f_running = False
            logging.info("Close process.")
Ejemplo n.º 10
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
Ejemplo n.º 11
0
def test():
    import time
    import json
    with open("sample.json") as f:
        t = json.load(f)
    t.append("namuyan" * 1024)
    s = time.time()

    pr_dump = cProfile.Profile()
    pr_dump.enable()
    bj = dumps(t)
    pr_dump.disable()
    print("encode", time.time() - s, "Sec")
    stats_dump = pstats.Stats(pr_dump)
    stats_dump.sort_stats('ncalls')
    stats_dump.print_stats()

    pr_load = cProfile.Profile()
    pr_load.enable()
    decoded = loads(bj)
    pr_load.disable()
    print("decode", time.time() - s, "Sec")
    stats_load = pstats.Stats(pr_load)
    stats_load.sort_stats('ncalls')
    stats_load.print_stats()

    print(len(bj) // 1000, "kB, match=", t == decoded)
Ejemplo n.º 12
0
def check_tx_create_contract(tx: TX, include_block: Block):
    if len(tx.inputs) == 0 or len(tx.outputs) == 0:
        raise BlockChainError('No inputs or outputs.')
    elif tx.message_type != C.MSG_BYTE:
        raise BlockChainError('create contract tx is bytes msg.')
    elif V.BLOCK_CONTRACT_PREFIX is None:
        raise BlockChainError('Not set contract prefix ?')
    elif V.BLOCK_CONTRACT_PREFIX == V.BLOCK_PREFIX:
        raise BlockChainError('normal prefix same with contract prefix.')
    # GAS量チェック
    estimate_gas = tx.getsize() + C.CONTRACT_CREATE_FEE
    if estimate_gas > tx.gas_amount:
        raise BlockChainError('Insufficient gas [{}>{}]'.format(
            estimate_gas, tx.gas_amount))
    # Contractをデコードできるか
    c_address, c_bin, c_cs = bjson.loads(tx.message)
    binary2contract(c_bin)
    # ContractStorageの初期値チェック
    if c_cs:
        for k, v in c_cs.items():
            if not isinstance(k, bytes) or not isinstance(v, bytes):
                raise BlockChainError('cs format is wrong. {}'.format(c_cs))
    if not is_address(c_address, V.BLOCK_CONTRACT_PREFIX):
        raise BlockChainError('Is not contract address. {}'.format(c_address))
    # 既に登録されていないかチェック
    cs = get_contract_storage(c_address, include_block)
    if cs.version != 0:
        raise BlockChainError('Already created contract. {}'.format(tx))
Ejemplo n.º 13
0
def _loop(v_address):
    while P.F_NOW_BOOTING:
        time.sleep(2)
    for tx in tx_builder.unconfirmed.values():
        if tx.type == C.TX_START_CONTRACT:
            P.VALIDATOR_OBJ.put_unvalidated(tx)

    # check validated start tx
    for tx in tx_builder.unconfirmed.values():
        if tx.type == C.TX_FINISH_CONTRACT:
            c_result, start_hash, cs_diff = bjson.loads(tx.message)
            start_tx = P.VALIDATOR_OBJ[start_hash]
            if start_tx:
                sign_pair = message2signature(tx.b, v_address)
                if sign_pair in tx.signature:
                    P.VALIDATOR_OBJ.put_validated(start_tx)

    logging.info("Enabled validator mode [{}].".format(v_address))
    while True:
        for start_tx in P.VALIDATOR_OBJ.get_unvalidated():
            finish_tx, estimate_gas = finish_contract_tx(start_tx)
            P.VALIDATOR_OBJ.put_validated(start_tx)
            finish_tx.signature.append(message2signature(finish_tx.b, v_address))
            print(estimate_gas, finish_tx)
            logging.info("Validated! {}".format(finish_tx))
            time.sleep(1)
        time.sleep(1)
Ejemplo n.º 14
0
async def conclude_contract(request):
    start = time()
    post = await web_base.content_type_json_check(request)
    try:
        start_hash = unhexlify(post['start_hash'].encode())
        start_tx = tx_builder.get_tx(txhash=start_hash)
        if start_tx is None:
            return web_base.error_res('Not found start_tx {}'.format(
                post['start_hash']))
        c_address, c_method, redeem_address, c_args = bjson.loads(
            start_tx.message)
        send_pairs = post.get('send_pairs', None)
        c_storage = post.get('storage', None)
        tx = create_conclude_tx(c_address=c_address,
                                start_tx=start_tx,
                                redeem_address=redeem_address,
                                send_pairs=send_pairs,
                                c_storage=c_storage)
        if not send_newtx(new_tx=tx):
            raise Exception('Failed to send new tx.')
        return web_base.json_res({
            'hash': hexlify(tx.hash).decode(),
            'gas_amount': tx.gas_amount,
            'gas_price': tx.gas_price,
            'fee': tx.gas_amount * tx.gas_price,
            'time': round(time() - start, 3)
        })
    except Exception:
        return web_base.error_res()
Ejemplo n.º 15
0
async def get_contract_history(request):
    try:
        c_address = request.query['c_address']
        data = list()
        # database
        for index, start_hash, finish_hash, (c_method, c_args, c_storage) in\
                builder.db.read_contract_iter(c_address=c_address):
            data.append({
                'index': index,
                'height': index // 0xffffffff,
                'start_hash': hexlify(start_hash).decode(),
                'finish_hash': hexlify(finish_hash).decode(),
                'c_method': c_method,
                'c_args': [decode(a) for a in c_args],
                'c_storage':
                {decode(k): decode(v)
                 for k, v in c_storage.items()} if c_storage else None
            })
        # memory
        for block in reversed(builder.best_chain):
            for tx in block.txs:
                if tx.type != C.TX_CONCLUDE_CONTRACT:
                    continue
                _c_address, start_hash, c_storage = bjson.loads(tx.message)
                if _c_address != c_address:
                    continue
                start_tx = tx_builder.get_tx(txhash=start_hash)
                dummy, c_method, redeem_address, c_args = bjson.loads(
                    start_tx.message)
                index = start_tx2index(start_tx=start_tx)
                data.append({
                    'index': index,
                    'height': tx.height,
                    'start_hash': hexlify(start_hash).decode(),
                    'finish_hash': hexlify(tx.hash).decode(),
                    'c_method': c_method,
                    'c_args': [decode(a) for a in c_args],
                    'c_storage':
                    {decode(k): decode(v)
                     for k, v in c_storage.items()} if c_storage else None,
                    # 'redeem_address': redeem_address,
                })
        return web_base.json_res(data)
    except Exception as e:
        logging.error(e)
        return web_base.error_res()
Ejemplo n.º 16
0
def finish_contract_tx(start_tx, f_limit=True):
    assert start_tx.height is None, 'StartTX height is None.'
    assert P.VALIDATOR_OBJ, 'You are not a validator.'
    c_address, c_data, c_args, c_redeem = bjson.loads(start_tx.message)
    if f_limit:
        gas_limit = start_tx.gas_amount - start_tx.getsize()
    else:
        gas_limit = None
    status, result, estimate_gas, line = try_emulate(start_tx, gas_limit)
    if status:
        # 成功時
        outputs, cs_result = result
        if cs_result is None:
            message = bjson.dumps((True, start_tx.hash, None), compress=False)
        else:
            cs = get_contract_storage(c_address)
            cs_diff = cs.diff_dev(new_key_value=cs_result.key_value)
            message = bjson.dumps((True, start_tx.hash, cs_diff),
                                  compress=False)
        try:
            check_output_format(outputs)
        except BlockChainError as e:
            logging.debug("Contract failed `emulate success` {}".format(e))
            return failed_finish_tx(start_tx), estimate_gas

    else:
        # 失敗時
        outputs = None
        logging.debug("Contract failed `emulate failed` {}".format(result))
        return failed_finish_tx(start_tx), 0
    # finish tx 作成
    finish_tx = TX(
        tx={
            'version': __chain_version__,
            'type': C.TX_FINISH_CONTRACT,
            'time': start_tx.time,
            'deadline': start_tx.deadline,
            'inputs': list(),
            'outputs': outputs or list(),
            'gas_price': start_tx.gas_price,
            'gas_amount': 1,
            'message_type': C.MSG_BYTE,
            'message': message
        })
    to_user_redeem = (c_redeem, 0, 0)
    finish_tx.outputs.append(to_user_redeem)  # gas_amountを返す
    # fill input/output
    # TODO: c_redeemを用いてFeeを還元
    redeem_gas = start_tx.gas_amount - start_tx.getsize() - estimate_gas
    if not fill_inputs_outputs(finish_tx, c_address, start_tx.hash,
                               redeem_gas):
        return failed_finish_tx(start_tx), estimate_gas
    redeem_idx = finish_tx.outputs.index(to_user_redeem)
    redeem_amount = -1 * finish_tx.gas_amount * finish_tx.gas_price
    finish_tx.outputs[redeem_idx] = (c_redeem, 0, redeem_amount)
    replace_redeem_dummy_address(finish_tx, c_address)
    finish_tx.serialize()
    return finish_tx, estimate_gas
Ejemplo n.º 17
0
def check_tx_mint_coin(tx, include_block):
    if not (0 < len(tx.inputs) and 0 < len(tx.outputs)):
        raise BlockChainError('Input and output is more than 1.')
    elif tx.message_type != C.MSG_BYTE:
        raise BlockChainError('TX_MINT_COIN message is bytes.')
    elif include_block and 0 == include_block.txs.index(tx):
        raise BlockChainError('tx index is not proof tx.')
    elif tx.gas_amount < tx.size + len(
            tx.signature) * C.SIGNATURE_GAS + C.MINTCOIN_GAS:
        raise BlockChainError('Insufficient gas amount [{}<{}+{}+{}]'.format(
            tx.gas_amount, tx.size,
            len(tx.signature) * C.SIGNATURE_GAS, C.MINTCOIN_GAS))
    # check new mintcoin format
    try:
        mint_id, params, setting = bjson.loads(tx.message)
    except Exception as e:
        raise BlockChainError('BjsonDecodeError: {}'.format(e))
    m_before = get_mintcoin_object(coin_id=mint_id,
                                   best_block=include_block,
                                   stop_txhash=tx.hash)
    result = check_mintcoin_new_format(m_before=m_before,
                                       new_params=params,
                                       new_setting=setting)
    if isinstance(result, str):
        raise BlockChainError('Failed check mintcoin block={}: {}'.format(
            include_block, result))
    # signature check
    require_cks, coins = input_output_digest(tx=tx)
    owner_address = m_before.address
    if owner_address:
        require_cks.add(owner_address)
    signed_cks = get_signed_cks(tx)
    if signed_cks != require_cks:
        raise BlockChainError(
            'Signature check failed. signed={} require={} lack={}'.format(
                signed_cks, require_cks, require_cks - signed_cks))
    # amount check
    if 0 < len(set(coins.keys()) - {0, mint_id}):
        raise BlockChainError('Unexpected coin_id included. {}'.format(
            set(coins.keys()) - {0, mint_id}))
    if mint_id in coins:
        # increase/decrease mintcoin amount
        if not m_before.setting['additional_issue']:
            raise BlockChainError(
                'additional_issue is False but change amount.')
        if coins[0] + coins[mint_id] < 0:
            raise BlockChainError('Too many output amount. {}'.format(coins))
        if coins[mint_id] < 0:
            pass  # increase
        if coins[mint_id] > 0:
            pass  # decrease
    else:
        # only change mintcoin status
        if params is None and setting is None:
            raise BlockChainError('No update found.')
        if sum(coins.values()) < 0:
            raise BlockChainError('Too many output amount. {}'.format(coins))
Ejemplo n.º 18
0
def check_tx_start_contract(start_tx: TX, include_block: Block):
    # 共通チェック
    c_address, c_data, c_args, c_redeem = bjson.loads(start_tx.message)
    if not is_address(c_address, V.BLOCK_CONTRACT_PREFIX):
        raise BlockChainError('Is not contract address. {}'.format(c_address))
    elif not (c_args is None or isinstance(c_args, list)
              or isinstance(c_args, tuple)):
        raise BlockChainError('c_args is {}'.format(type(c_args)))
    elif not is_address(c_redeem, V.BLOCK_PREFIX):
        raise BlockChainError('Is not redeem address. {}'.format(c_redeem))
    elif start_tx.gas_price < V.COIN_MINIMUM_PRICE:
        raise BlockChainError('GasPrice is too low. [{}<{}]'.format(
            start_tx.gas_price, V.COIN_MINIMUM_PRICE))
    elif start_tx.gas_amount < V.CONTRACT_MINIMUM_AMOUNT:
        raise BlockChainError('GasAmount is too low. [{}<{}]'.format(
            start_tx.gas_amount, V.CONTRACT_MINIMUM_AMOUNT))

    # Block内チェック
    if include_block:
        # 同一のStartTXを示すFinishTXが存在しないかチェック
        count = 0
        for finish_tx in include_block.txs:
            if finish_tx.type != C.TX_FINISH_CONTRACT:
                continue
            c_status, c_start_hash, c_diff = bjson.loads(finish_tx.message)
            if c_start_hash != start_tx.hash:
                continue
            count += 1
        if count == 0:
            raise BlockChainError(
                'Not found FinishTX on block. {}'.format(start_tx))
        if count > 1:
            raise BlockChainError(
                'Find some FinishTX on block. {}'.format(count))

    else:
        c_address, c_method, c_args, c_redeem = bjson.loads(start_tx.message)
        get_contract_binary(c_address)
        if P.VALIDATOR_OBJ and im_a_validator(include_block):
            P.VALIDATOR_OBJ.put_unvalidated(start_tx)
            logging.debug("Add validation que {}".format(start_tx))
Ejemplo n.º 19
0
def create_signed_tx_as_validator(tx: TX):
    assert tx.type in (C.TX_VALIDATOR_EDIT, C.TX_CONCLUDE_CONTRACT)
    assert tx.hash in tx_builder.unconfirmed
    copied_tx = deepcopy(tx)
    # sign as another validator
    c_address, *dummy = bjson.loads(copied_tx.message)
    # validator object
    stop_txhash = copied_tx.hash if copied_tx.type == C.TX_VALIDATOR_EDIT else None
    v = get_validator_object(c_address=c_address, stop_txhash=stop_txhash)
    if setup_contract_signature(copied_tx, v.validators) == 0:
        raise BlockChainError('Cannot sign, you are not validator.')
    return copied_tx
Ejemplo n.º 20
0
 def deserialize(self):
     d = bjson.loads(self.binary)
     self.version = d['version']
     self.coin_id = d['coin_id']
     self.name = d.get('name')
     self.unit = d.get('unit')
     self.digit = d.get('digit')
     self.amount = d['amount']
     self.additional_issue = d.get('additional_issue')
     self.owner = d['owner']
     self.image = d.get('image')
     self.sign = d['sign']
     self.message = d.get('message')
Ejemplo n.º 21
0
def get_contract_binary(c_address, best_block=None, best_chain=None):
    assert V.CONTRACT_VALIDATOR_ADDRESS, 'Not found validator address.'
    if c_address == V.CONTRACT_VALIDATOR_ADDRESS:
        return contract2binary(Contract)
    # DataBaseより
    for dummy, index, start_hash, finish_hash in builder.db.read_contract_iter(c_address):
        start_tx = tx_builder.get_tx(start_hash)
        dummy, c_bin, c_cs = bjson.loads(start_tx.message)
        return c_bin
    # Memoryより
    best_chain = best_chain or _get_best_chain_all(best_block)
    for block in reversed(best_chain):
        for tx in block.txs:
            if tx.type == C.TX_CREATE_CONTRACT:
                dummy, c_bin, c_cs = bjson.loads(tx.message)
                return c_bin
    # Unconfirmedより
    if best_block is None:
        for tx in sorted(tx_builder.unconfirmed.values(), key=lambda x: x.time):
            if tx.type == C.TX_CREATE_CONTRACT:
                dummy, c_bin, c_cs = bjson.loads(tx.message)
                return c_bin
    return None
Ejemplo n.º 22
0
def get_contract_storage(c_address, best_block=None, best_chain=None):
    # DataBaseより
    cs = ContractStorage()
    for dummy, index, start_hash, finish_hash in builder.db.read_contract_iter(c_address):
        if index == 0:
            start_tx = tx_builder.get_tx(start_hash)
            dummy, c_bin, c_cs = bjson.loads(start_tx.message)
            cs.key_value = c_cs or dict()
        else:
            finish_tx = tx_builder.get_tx(finish_hash)
            c_status, dummy, c_diff = bjson.loads(finish_tx.message)
            cs.marge(c_diff)
    # Memoryより
    best_chain = best_chain or _get_best_chain_all(best_block)
    for block in reversed(best_chain):
        for tx in block.txs:
            if tx.type == C.TX_CREATE_CONTRACT:
                check_address, c_bin, c_cs = bjson.loads(tx.message)
                if c_address == check_address:
                    cs.key_value = c_cs or dict()
            elif tx.type == C.TX_START_CONTRACT:
                pass
            elif tx.type == C.TX_FINISH_CONTRACT:
                c_status, start_hash, c_diff = bjson.loads(tx.message)
                start_tx = tx_builder.get_tx(start_hash)
                check_address, c_bin, c_cs = bjson.loads(start_tx.message)
                if c_address == check_address:
                    cs.marge(c_diff)
    # Unconfirmedより
    if best_block is None:
        for tx in sorted(tx_builder.unconfirmed.values(), key=lambda x: x.time):
            if tx.type == C.TX_CREATE_CONTRACT:
                check_address, c_bin, c_cs = bjson.loads(tx.message)
                cs.key_value = c_cs or dict()
            elif tx.type == C.TX_START_CONTRACT:
                pass
            elif tx.type == C.TX_FINISH_CONTRACT:
                c_status, start_hash, c_diff = bjson.loads(tx.message)
                start_tx = tx_builder.get_tx(start_hash)
                check_address, c_bin, c_cs = bjson.loads(start_tx.message)
                if c_address == check_address:
                    cs.marge(c_diff)
    return cs
Ejemplo n.º 23
0
def check_tx_finish_contract(finish_tx, include_block):
    if finish_tx.message_type != C.MSG_BYTE:
        raise BlockChainError('message type is bytes.')
    finish_status, start_hash, finish_diff = bjson.loads(finish_tx.message)
    # StartTXを探し出す
    start_tx = get_start_by_finish_tx(finish_tx, start_hash, include_block)
    # FinishTXとStartTXの整合性チェック
    if start_tx.gas_price != finish_tx.gas_price:
        raise BlockChainError(
            'StartGasPrice differ from FinishGasPrice. [{}!={}]'.format(
                start_tx.gas_price, finish_tx.gas_price))
    elif finish_tx.gas_amount > 0:
        raise BlockChainError('Not redeem amount found. [{}>0]'.format(
            finish_tx.gas_amount))
    elif include_block:
        if include_block.txs.index(start_tx) >= include_block.txs.index(
                finish_tx):
            raise BlockChainError(
                'start tx index is higher than finish tx. [{}>={}]'.format(
                    include_block.txs.index(start_tx),
                    include_block.txs.index(finish_tx)))
Ejemplo n.º 24
0
async def get_validator_history(request):
    try:
        c_address = request.query['c_address']
        data = list()
        # database
        for index, new_address, flag, txhash, sig_diff in builder.db.read_validator_iter(
                c_address=c_address):
            data.append({
                'index': index,
                'height': None,
                'new_address': new_address,
                'flag': flag,
                'txhash': hexlify(txhash).decode(),
                'sig_diff': sig_diff
            })
        # memory
        index = len(data)
        for block in reversed(builder.best_chain):
            for tx in block.txs:
                if tx.type != C.TX_VALIDATOR_EDIT:
                    continue
                _c_address, new_address, flag, sig_diff = bjson.loads(
                    tx.message)
                if _c_address != c_address:
                    continue
                data.append({
                    'index': index,
                    'height': tx.height,
                    'new_address': new_address,
                    'flag': flag,
                    'txhash': hexlify(tx.hash).decode(),
                    'sig_diff': sig_diff
                })
                index += 1
        return web_base.json_res(data)
    except Exception as e:
        logging.error(e)
        return web_base.error_res()
Ejemplo n.º 25
0
Archivo: builder.py Proyecto: kmn/bc4py
    def batch_apply(self, force=False):
        # 無チェックで挿入するから要注意
        if not force and self.cashe_limit > len(self.chain):
            return list()
        # cashe許容量を上回っているので記録
        self.db.batch_create()
        logging.debug("Start batch apply. chain={} force={}".format(len(self.chain), force))
        best_chain = self.best_chain.copy()
        batch_count = self.batch_size
        batched_blocks = list()
        with closing(create_db(V.DB_ACCOUNT_PATH)) as db:
            cur = db.cursor()  # DO NOT USE FOR WRITE!
            try:
                block = None
                while batch_count > 0 and len(best_chain) > 0:
                    batch_count -= 1
                    block = best_chain.pop()  # 古いものから順に
                    batched_blocks.append(block)
                    self.db.write_block(block)  # Block
                    assert len(block.txs) > 0, "found no tx in {}".format(block)
                    for tx in block.txs:
                        self.db.write_tx(tx)  # TX
                        # inputs
                        for index, (txhash, txindex) in enumerate(tx.inputs):
                            # DataBase内でのみのUsedIndexを取得
                            usedindex = self.db.read_usedindex(txhash)
                            if txindex in usedindex:
                                raise BlockBuilderError('Already used index? {}:{}'
                                                        .format(hexlify(txhash).decode(), txindex))
                            usedindex.add(txindex)
                            self.db.write_usedindex(txhash, usedindex)  # UsedIndex update
                            input_tx = tx_builder.get_tx(txhash)
                            address, coin_id, amount = input_tx.outputs[txindex]
                            if config['full_address_index'] or is_address(ck=address, prefix=V.BLOCK_CONTRACT_PREFIX)\
                                    or read_address2user(address=address, cur=cur):
                                # 必要なAddressのみ
                                self.db.write_address_idx(address, txhash, txindex, coin_id, amount, True)
                        # outputs
                        for index, (address, coin_id, amount) in enumerate(tx.outputs):
                            if config['full_address_index'] or is_address(ck=address, prefix=V.BLOCK_CONTRACT_PREFIX) \
                                    or read_address2user(address=address, cur=cur):
                                # 必要なAddressのみ
                                self.db.write_address_idx(address, tx.hash, index, coin_id, amount, False)
                        # TXの種類による追加操作
                        if tx.type == C.TX_GENESIS:
                            pass
                        elif tx.type == C.TX_TRANSFER:
                            pass
                        elif tx.type == C.TX_POW_REWARD:
                            pass
                        elif tx.type == C.TX_POS_REWARD:
                            pass
                        elif tx.type == C.TX_MINT_COIN:
                            mint_id, params, setting = bjson.loads(tx.message)
                            self.db.write_coins(coin_id=mint_id, txhash=tx.hash, params=params, setting=setting)

                        elif tx.type == C.TX_VALIDATOR_EDIT:
                            c_address, new_address, flag, sig_diff = bjson.loads(tx.message)
                            self.db.write_validator(c_address=c_address, new_address=new_address,
                                                    flag=flag, tx=tx, sign_diff=sig_diff)

                        elif tx.type == C.TX_CONCLUDE_CONTRACT:
                            c_address, start_hash, c_storage = bjson.loads(tx.message)
                            start_tx = tx_builder.get_tx(txhash=start_hash)
                            dummy, c_method, redeem_address, c_args = bjson.loads(start_tx.message)
                            self.db.write_contract(c_address=c_address, start_tx=start_tx,
                                                   finish_hash=tx.hash, message=(c_method, c_args, c_storage))

                # block挿入終了
                self.best_chain = best_chain
                self.root_block = block
                self.db.batch_commit()
                self.save_starter()
                # root_blockよりHeightの小さいBlockを消す
                for blockhash, block in self.chain.copy().items():
                    if self.root_block.height >= block.height:
                        del self.chain[blockhash]
                logging.debug("Success batch {} blocks, root={}."
                              .format(len(batched_blocks), self.root_block))
                # アカウントへ反映↓
                user_account.new_batch_apply(batched_blocks)
                return batched_blocks  # [<height=n>, <height=n+1>, .., <height=n+m>]
            except Exception as e:
                self.db.batch_rollback()
                logging.warning("Failed batch block builder. '{}'".format(e), exc_info=True)
                return list()
Ejemplo n.º 26
0
def check_tx_validator_edit(tx: TX, include_block: Block):
    # common check
    if not (len(tx.inputs) > 0 and len(tx.inputs) > 0):
        raise BlockChainError('No inputs or outputs.')
    elif tx.message_type != C.MSG_BYTE:
        raise BlockChainError('validator_edit_tx is bytes msg.')
    elif V.BLOCK_CONTRACT_PREFIX is None:
        raise BlockChainError('Not set contract prefix ?')
    elif V.BLOCK_CONTRACT_PREFIX == V.BLOCK_PREFIX:
        raise BlockChainError('normal prefix same with contract prefix.')
    # message
    try:
        c_address, new_address, flag, sig_diff = bjson.loads(tx.message)
    except Exception as e:
        raise BlockChainError('BjsonError: {}'.format(e))
    # inputs/outputs address check
    for txhash, txindex in tx.inputs:
        input_tx = tx_builder.get_tx(txhash)
        if input_tx is None:
            raise BlockChainError('Not found input tx.')
        address, coin_id, amount = input_tx.outputs[txindex]
        if address != c_address:
            raise BlockChainError('1 Not contract address. {}'.format(address))
    for address, coin_id, amount in tx.outputs:
        if address != c_address:
            raise BlockChainError('2 Not contract address. {}'.format(address))
    # check new_address
    v_before = get_validator_object(c_address=c_address, best_block=include_block, stop_txhash=tx.hash)
    if new_address:
        if not is_address(ck=new_address, prefix=V.BLOCK_PREFIX):
            raise BlockChainError('new_address is normal prefix.')
        elif flag == F_NOP:
            raise BlockChainError('input new_address, but NOP.')
    if v_before.index == -1:
        # create validator for the first time
        if new_address is None:
            raise BlockChainError('Not setup new_address.')
        elif flag != F_ADD:
            raise BlockChainError('Need to add new_address flag.')
        elif sig_diff != 1:
            raise BlockChainError('sig_diff is 1.')
    else:
        # edit already created validator
        next_validator_num = len(v_before.validators)  # Note: Add/Remove after
        next_require_num = v_before.require + sig_diff
        if flag == F_ADD:
            if new_address is None:
                raise BlockChainError('Not setup new_address.')
            elif new_address in v_before.validators:
                raise BlockChainError('Already included new_address.')
            next_validator_num += 1
        elif flag == F_REMOVE:
            if new_address is None:
                raise BlockChainError('Not setup new_address.')
            elif new_address not in v_before.validators:
                raise BlockChainError('Not include new_address.')
            elif len(v_before.validators) < 2:
                raise BlockChainError('validator is now only {}.'.format(len(v_before.validators)))
            next_validator_num -= 1
        elif flag == F_NOP:
            if new_address is not None:
                raise BlockChainError('Input new_address?')
        else:
            raise BlockChainError('unknown flag {}.'.format(flag))
        # sig_diff check
        if not (0 < next_require_num <= next_validator_num):
            raise BlockChainError('sig_diff check failed, 0 < {} <= {}.'
                                  .format(next_require_num, next_validator_num))
    contract_required_gas_check(tx=tx, v=v_before, extra_gas=C.VALIDATOR_EDIT_GAS)
    contract_signature_check(extra_tx=tx, v=v_before, include_block=include_block)
Ejemplo n.º 27
0
def check_tx_contract_conclude(tx: TX, include_block: Block):
    # common check
    if not (len(tx.inputs) > 0 and len(tx.inputs) > 0):
        raise BlockChainError('No inputs or outputs.')
    elif tx.message_type != C.MSG_BYTE:
        raise BlockChainError('validator_edit_tx is bytes msg.')
    elif V.BLOCK_CONTRACT_PREFIX is None:
        raise BlockChainError('Not set contract prefix ?')
    elif V.BLOCK_CONTRACT_PREFIX == V.BLOCK_PREFIX:
        raise BlockChainError('normal prefix same with contract prefix.')
    try:
        c_address, start_hash, c_storage = bjson.loads(tx.message)
    except Exception as e:
        raise BlockChainError('BjsonError: {}'.format(e))
    if not (isinstance(c_address, str) and len(c_address) == 40):
        raise BlockChainError('1. Not correct format. {}'.format(c_address))
    if not (isinstance(start_hash, bytes) and len(start_hash) == 32):
        raise BlockChainError('2. Not correct format. {}'.format(start_hash))
    if not (c_storage is None or isinstance(c_storage, dict)):
        raise BlockChainError('3. Not correct format. {}'.format(c_storage))
    # check already created conclude tx
    check_finish_hash = get_conclude_hash_by_start_hash(
        c_address=c_address, start_hash=start_hash, best_block=include_block, stop_txhash=tx.hash)
    if check_finish_hash is not None:
        raise BlockChainError('Already start_hash used. {}'.format(hexlify(check_finish_hash).decode()))
    # inputs address check
    for txhash, txindex in tx.inputs:
        input_tx = tx_builder.get_tx(txhash)
        if input_tx is None:
            raise BlockChainError('Not found input tx.')
        address, coin_id, amount = input_tx.outputs[txindex]
        if address != c_address:
            raise BlockChainError('Not contract address. {}'.format(address))
    # validator check
    v = get_validator_object(c_address=c_address, best_block=include_block, stop_txhash=tx.hash)
    if v.require == 0:
        raise BlockChainError('At least 1 validator required. {}'.format(v.require))
    # check start tx
    start_tx = tx_builder.get_tx(txhash=start_hash)
    if start_tx is None:
        raise BlockChainError('Not found start tx. {}'.format(hexlify(start_hash).decode()))
    if start_tx.height is None:
        raise BlockChainError('Start tx is unconfirmed. {}'.format(start_tx))
    if start_tx.type != C.TX_TRANSFER:
        raise BlockChainError('Start tx is TRANSFER, not {}.'.format(C.txtype2name.get(start_tx.type, None)))
    if start_tx.message_type != C.MSG_BYTE:
        raise BlockChainError('Start tx is MSG_BYTE, not {}.'.format(C.msg_type2name.get(start_tx.message_type, None)))
    if start_tx.time != tx.time or start_tx.deadline != tx.deadline:
        raise BlockChainError('time of conclude_tx and start_tx is same, {}!={}.'.format(start_tx.time, tx.time))
    try:
        c_start_address, c_method, c_args = bjson.loads(start_tx.message)
    except Exception as e:
        raise BlockChainError('BjsonError: {}'.format(e))
    if c_address != c_start_address:
        raise BlockChainError('Start tx\'s contract address is different. {}!={}'.format(c_address, c_start_address))
    if not isinstance(c_method, str):
        raise BlockChainError('c_method is string. {}'.format(c_method))
    if not (isinstance(c_args, tuple) or isinstance(c_args, list)):
        raise BlockChainError('4. Not correct format. {}'.format(c_args))
    # contract check
    c_before = get_contract_object(c_address=c_address, best_block=include_block, stop_txhash=tx.hash)
    if c_method == M_INIT:
        if len(c_args) != 3:
            raise BlockChainError('c_args is 3 items.')
        if c_before.index != -1:
            raise BlockChainError('Already created contract. {}'.format(c_before.index))
        c_bin, c_extra_imports, c_settings = c_args
        if not isinstance(c_bin, bytes):
            raise BlockChainError('5. Not correct format. {}'.format(c_args))
        if not (c_extra_imports is None or isinstance(c_extra_imports, tuple) or isinstance(c_extra_imports, list)):
            raise BlockChainError('6. Not correct format. {}'.format(c_extra_imports))
        if not (c_settings is None or isinstance(c_settings, dict)):
            raise BlockChainError('7. Not correct format. {}'.format(c_settings))
    elif c_method == M_UPDATE:
        if len(c_args) != 3:
            raise BlockChainError('c_args is 3 items.')
        if c_before.index == -1:
            raise BlockChainError('Not created contract.')
        c_bin, c_extra_imports, c_settings = c_args
        if not (c_bin is None or isinstance(c_bin, bytes)):
            raise BlockChainError('8. Not correct format. {}'.format(c_args))
        if not (c_extra_imports is None or isinstance(c_extra_imports, tuple)):
            raise BlockChainError('9. Not correct format. {}'.format(c_extra_imports))
        if not (c_settings is None or isinstance(c_settings, dict)):
            raise BlockChainError('10. Not correct format. {}'.format(c_settings))
        if not (c_bin or c_extra_imports or c_settings):
            raise BlockChainError('No change found. {}, {}, {}'.format(c_bin, c_extra_imports, c_settings))
    else:
        pass  # user oriented data
    contract_required_gas_check(tx=tx, v=v, extra_gas=0)
    contract_signature_check(extra_tx=tx, v=v, include_block=include_block)
Ejemplo n.º 28
0
def decode(b):
    # transfer: [c_address]-[c_method]-[redeem_address]-[c_args]
    # conclude: [c_address]-[start_hash]-[c_storage]
    return bjson.loads(b)
Ejemplo n.º 29
0
def try_emulate(start_tx, gas_limit=None, out=None):
    start_time = time.time()
    cxt = get_context('spawn')
    que = cxt.Queue()
    # out = out or io.StringIO()
    c_address, c_method, c_args, c_redeem = bjson.loads(start_tx.message)
    c_bin = get_contract_binary(c_address)
    assert c_bin, 'Not found c_bin of {}'.format(c_address)
    params = {
        'sub_dir': V.SUB_DIR, 'genesis_block': builder.get_block(builder.get_block_hash(0)),
        'c_bin': c_bin, 'c_address': c_address, 'c_method': c_method, 'args': c_args}
    p = cxt.Process(target=_work, args=(params, start_tx, que))
    p.start()
    que_cmd, port = que.get(timeout=10)
    if que_cmd != CMD_PORT:
        raise TypeError('Not correct command="{}" data="{}"'.format(que_cmd, port))
    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    sock.connect(("127.0.0.1", port))
    sock.settimeout(10)
    # Start emulation
    line = fee = 0
    cmd = EMU_STEP
    error = None
    logging.debug("Start contract emulate port={}".format(port))
    while True:
        try:
            msg_list = sock.recv(8192).decode(errors='ignore').replace("\r", "").split("\n")
            if len(msg_list) <= 1:
                sock.close()
                break
            elif len(msg_list) < 3:
                pass
            elif gas_limit and fee > gas_limit:
                error = 'reached gas limit. [{}>{}]'.format(fee, gas_limit)
                break
            elif cmd in (EMU_STEP, EMU_NEXT, EMU_UNTIL, EMU_RETURN):
                msg_list, path, words = msg_list[:-3], msg_list[-3][2:], msg_list[-2][3:]
                file = os.path.split(path)[1]
                print(file, words, path)
                if file.startswith('exe.py') and file.endswith('work_field()'):
                    cmd = EMU_STEP  # Start!
                    print("start contract {}", file=out)
                elif file.startswith('contract('):
                    line += 1
                    fee += 1
                    cmd = EMU_STEP
                else:
                    cmd = EMU_NEXT
                # Add fee
                for func, gas in __price__.items():
                    if func in words and words.startswith('def ' + func + '('):
                        fee += gas
                print("{}:read [{}] {} >> {}".format(line, fee, cmd, words), file=out)
            else:
                msg = ', '.join(msg_list)
                print("msg [{}] >>".format(cmd), msg, file=out)
            # response to work field
            sock.send((cmd + "\n").encode())
        except ConnectionResetError:
            break
        except BaseException:
            error = str(traceback.format_exc())
            break
    logging.debug("Finish contract {}Sec error:{}".format(round(time.time() - start_time, 3), error))
    # Close emulation
    try:
        que_cmd, result = que.get_nowait()
        print(result)
        try: que.close()
        except: pass
        try: p.terminate()
        except: pass
        if que_cmd == CMD_ERROR:
            return False, result, fee, line
        elif que_cmd == CMD_SUCCESS:
            return True, result, fee, line
    except BaseException:
        return False, error, fee, line
Ejemplo n.º 30
0
def get_tx_message_data(tx):
    return bjson.loads(tx.message)[1]