Esempio n. 1
0
def relay_message(inv, obj):
    if isinstance(obj, serialize.PyDataStream):
        ss = obj
    elif isinstance(obj, serialize.Serializable):
        ss = serialize.PyDataStream(nType=serialize.SerType.SER_NETWORK)
        ss.stream_in(obj, in_type="Serializable")
    else:
        raise TypeError(
            "relay_message can only relay Serializable class and PyDataStream")

    with ctx.dictRelayLock:
        # Expire old relay messages
        while len(
                ctx.listRelayExpiration
        ) != 0 and ctx.listRelayExpiration[0][0] < timeutil.get_time():
            relay_tuple = ctx.listRelayExpiration.popleft(
            )  # relay_tuple = (time ,PyInv)
            ctx.dictRelay.pop(
                relay_tuple[1])  # dictRelay = dict<PyInv, PyDataStream>
        # Save original serialized message so newer versions are preserved
        ctx.dictRelay[inv] = ss
        ctx.listRelayExpiration.append(
            (timeutil.get_time() + cfg.INV_EXPIRED_TIME, inv))  # 当前时间加上 15 min
    relay_inventory(inv)
    pass
Esempio n. 2
0
def genesis_block():
    timestamp = "The Times 22/Mar/2017 Chancellor on brink of second bailout for banks"
    tx_new = Tx.PyTransaction()
    txin = Tx.PyTxIn()
    init_nbits = 0x1f00ffff
    sig = Script.PyScript().append(init_nbits).append_num(4).extend(timestamp)
    # script << nbits << extra_nonce
    txin.script_sig = sig
    txout = Tx.PyTxOut()
    txout.value = 50 * cfg.COIN
    # scriptPubKey << OP_DUP << OP_HASH160 << hash160 << OP_EQUALVERIFY << OP_CHECKSIG;   Hash160(pubkey)  # txNew.vout[0].scriptPubKey << key.GetPubKey() << OP_CHECKSIG;
    # txNew.vout[0].scriptPubKey = CScript() << CBigNum("0x5F1DF16B2B704C8A578D0BBAF74D385CDE12C11EE50455F3C438EF4C3FBCF649B6DE611FEAE06279A60939E028A8D65C10B73071A6F16719274855FEB0FD8A6704") << OP_CHECKSIG;
    txout.script_pubkey = Script.PyScript().extend(binascii.unhexlify(cfg.GENESIS_PUBKEY)) \
        .append(Script.OpCodeType.OP_CHECKSIG)

    tx_new.l_in.append(txin)
    tx_new.l_out.append(txout)
    block = Block.PyBlock()
    block.l_tx.append(tx_new)
    block.hash_prev_block = 0
    block.hash_merkle_root = block.build_merkle_tree()
    block.version = 1
    block.time = 1490092537
    # block.bits = 0x2000ffff  #
    block.bits = init_nbits  # nonce:45164 hash:2e72d19b7558bd6ec869e5601c3613cc7a6b3f24118773d7aaaa3c285493fdfc
    # block.bits = 0x1e00ffff  # nonce:xxx (cast almost 5 min)
    block.nonce = 0
    hash_target = BN.PyBigNum.set_compact(block.bits).get_uint256()
    target_hex = serialize.hexser_uint256(hash_target)
    # target_hex = long(hash_target)
    time1 = timeutil.get_time()
    print 'start time:', time1
    while True:
        block_hash = cryptoutil.Hash(block.serialize())
        print 'nonce:', block.nonce
        print 'now hash:'
        print serialize.hexser_uint256(block_hash)
        # print long(block_hash)
        print 'target'
        print target_hex
        if block_hash <= hash_target:
            print 'current nonce:'
            print block.nonce
            print binascii.hexlify(serialize.ser_uint256(block.get_hash()))
            print block.get_hash('hex')
            print long(hash_target)
            break
        block.nonce += 1
    time2 = timeutil.get_time()
    print 'end time:', time2
    diff = time2 - time1
    print("%d:%d" % (diff / 60, diff % 60))
Esempio n. 3
0
    def accept_review(self):
        """

        :return:
        :rtype bool
        """
        time = timeutil.get_time()  # timestamp
        # check signature
        if not PyKey.static_verify(
                self.pubkey_from, self.get_sig_hash(out_type='str'), self.sig):
            return False

        reviewdb = PyReviewDB()

        # Add review text to recipient
        reviews = reviewdb.read_reviews(self.hash_to)  # list<PyReview>
        reviews.append(self)
        reviewdb.write_reviews(self.hash_to, reviews)

        # Add link from sender
        user = PyUser()
        hash_from = cryptoutil.Hash(self.pubkey_from)
        reviewdb.read_user(hash_from)
        user.links_out.append(self.hash_to)
        reviewdb.write_user(hash_from, user)

        reviewdb.close()

        if not add_atoms_and_propagate(
                self.hash_to,
                user.atoms_out if len(user.atoms_out) > 0 else [0], False):
            return False
        return True
Esempio n. 4
0
    def OnIdle(self, event):
        if self.f_refresh_listctrl:
            # Collect list of wallet transactions and sort newest first
            f_entered = False
            list_sorted = list()
            if ctx.dictWalletLock._RLock__count == 0:
                with ctx.dictWalletLock:
                    print("RefreshListCtrl starting")
                    f_entered = True
                    self.f_refresh_listctrl = False
                    del ctx.listWalletUpdated[:]

                    # Do the newest transactions first
                    for tx_hash, wtx in ctx.dictWallet.iteritems():
                        time = 0xFFFFFFFF - wtx.get_tx_time()
                        list_sorted.append((time, tx_hash))
                    self.m_listCtrl_txs.DeleteAllItems()
                    pass  # end block
                pass  # end try block

            if not f_entered:
                return

            list_sorted.sort(key=lambda x: x[0])

            # Fill list control
            for i, item in enumerate(list_sorted):
                if ctx.fShutdown:
                    return
                f_entered = False
                if ctx.dictWalletLock._RLock__count == 0:
                    with ctx.dictWalletLock:
                        f_entered = True
                        tx_hash = item[1]
                        wtx = ctx.dictWallet.get(tx_hash, None)
                        if wtx is not None:
                            self.InsertTransaction(wtx, True)
                        pass  # end block
                    pass  # end try block
                if not f_entered or i == 100 or i % 500 == 0:
                    wx.Yield()
            print("RefreshListCtrl done")
        else:
            # Check for time updates
            current_time = timeutil.get_time()
            if current_time > MainFrame.nLastTime + 30:
                if ctx.dictWalletLock._RLock__count == 0:
                    with ctx.dictWalletLock:
                        MainFrame.nLastTime = current_time
                        for wtx in ctx.dictWallet.values():
                            if wtx.time_displayed and wtx.time_displayed != wtx.get_tx_time:
                                self.InsertTransaction(wtx, False)

            pass
        pass  # end func
Esempio n. 5
0
def connect_node(addr_conn, timeout=0):
    """

    :param addr_conn:
    :type addr_conn: PyAddress
    :param timeout:
    :return:
    :rtype net.PyNode
    """
    if addr_conn.ip == net.addrLocalHost.ip:
        return None
    # Look for an existing connection
    node = find_node(addr_conn.ip)
    if node:
        if timeout != 0:
            node.add_ref(timeout)
        else:
            node.add_ref()
        return node

    # debug
    print("trying %s" % str(addr_conn))
    # connect
    # hsocket = socket.socket()  # (socket.AF_INET, socket.SOCK_STREAM)
    # The error indicator is 0 if the operation succeeded, otherwise the value of the errno variable
    hsocket = netbase.connect_socket(addr_conn)
    if hsocket is not None:
        # debug print
        print "connected %s" % str(addr_conn)

        # add node
        node = net.PyNode(hsocket, addr_conn, False)
        if timeout != 0:
            node.add_ref(timeout)
        else:
            node.add_ref()

        with ctx.listNodesLock:
            ctx.listNodes.append(node)
        with ctx.dictAddressesLock:
            ctx.dictAddresses[addr_conn.get_key()].last_failed = 0
        return node
    else:  # connect failed
        with ctx.dictAddressesLock:
            ctx.dictAddresses[
                addr_conn.get_key()].last_failed = timeutil.get_time()
        return None
    pass
Esempio n. 6
0
    def __init__(self, parent=None):
        super(MainFrame, self).__init__(parent=parent)
        self.Bind(EVT_CROSSTHREADCALL, self.OnCrossThreadCall)

        # init
        self.f_refresh_listctrl = False
        self.f_refresh_listctrl_running = False
        self.f_on_setfouces_addr = False
        self.index_best_last = None
        self.set_unmatured_displayed = set()

        self.m_choicefilter.SetSelection(0)
        self.m_statictext_balance.SetLabel(
            util.format_money(txaction.get_balance()) + "  ")
        self.m_listCtrl_txs.SetFocus()
        self.SetIcon(wx.Icon(load_img_path(u"bitcoin.ico")))
        self.m_menuOptions.Check(wxID_OPTIONSGENERATEBITCOINS,
                                 ctx.fGenerateCoins)

        # init column headers
        date_width = len(timeutil.date_time_str(timeutil.get_time())) * 6 + 8
        self.m_listCtrl_txs.InsertColumn(0, "", wx.LIST_FORMAT_LEFT, 0)
        self.m_listCtrl_txs.InsertColumn(1, "", wx.LIST_FORMAT_LEFT, 0)
        self.m_listCtrl_txs.InsertColumn(2, "Status", wx.LIST_FORMAT_LEFT, 90)
        self.m_listCtrl_txs.InsertColumn(3, "Date", wx.LIST_FORMAT_LEFT,
                                         date_width)
        self.m_listCtrl_txs.InsertColumn(4, "Description", wx.LIST_FORMAT_LEFT,
                                         409 - date_width)
        self.m_listCtrl_txs.InsertColumn(5, "Debit", wx.LIST_FORMAT_RIGHT, 79)
        self.m_listCtrl_txs.InsertColumn(6, "Credit", wx.LIST_FORMAT_RIGHT, 79)

        # Init status bar
        widths = [-80, 150, 286]
        self.m_statusBar.SetFieldsCount(3)
        self.m_statusBar.SetStatusWidths(widths)
        with Tx.PyWalletDB("r") as walletdb:
            default_key = walletdb.read_default_key()
        if default_key is not None:
            self.m_textCtrl_addr.SetValue(
                keyaction.pubkey_to_addr(default_key))
        self.RefreshListCtrl()

        ctx.frameMain = self

        self.miner_thread = None
        pass
Esempio n. 7
0
    def OnIdle(self, event):
        current_time = timeutil.get_time()
        if current_time - WaitThreadsDialog.nLastTime > 1:  # lookup every 1 second
            WaitThreadsDialog.nLastTime = current_time
        else:
            return

        for i, data in enumerate(ctx.listWorkThreads):
            t, name = data
            s = "run" if t.isAlive() else "exit"
            ret = "%s: %s" % (name, s)
            self.text_list[i].SetLabelText(ret)
        if self.parent.miner_thread is not None:
            s = "run" if self.parent.miner_thread.isAlive() else "exit"
            ret = "%s: %s" % ("miner coin", s)
            self.m_staticText_thread4.SetLabelText(ret)
        else:
            self.m_staticText_thread4.SetLabelText("miner coin: not working")
        pass
Esempio n. 8
0
def send_messages(node_to, t, ignore=False):
    """

    :param node_to:
    :type node_to: net.PyNode
    :param t:
    :type t: ExitedThread
    :return:
    """
    t.check_self_shutdown()
    with ctx.mainLock:
        #  Don't send anything until we get their version message
        if node_to.nVersion == 0:
            return True

        # Message: addr
        list_addr_to_send = [
            addr for addr in node_to.list_addr_to_send
            if addr not in node_to.set_addr_known
        ]
        del node_to.list_addr_to_send[:]
        if list_addr_to_send:
            node_to.push_message(base.COMMAND_ADDR,
                                 list_addr_to_send,
                                 ignore=ignore)

        # Message: inventory
        list_inventory_to_send = list()
        with node_to.inventory_lock:
            for inv in node_to.list_inventory_to_send:
                if inv not in node_to.set_inventory_know:
                    node_to.set_inventory_know.add(inv)
                    list_inventory_to_send.append(inv)

            del node_to.list_inventory_to_send[:]  # clear element in node.list_inventory_to_send, not local var
            node_to.set_inventory_know2.clear()  # 注意这里clear的是 2

        if list_inventory_to_send:
            node_to.push_message(base.COMMAND_INV,
                                 list_inventory_to_send,
                                 ignore=ignore)

        # Message: getdata
        now = timeutil.get_time() * 1000000  # usec
        txdb = Tx.PyTxDB("r")
        list_ask_for = list()
        dict_ask_for = node_to.dict_ask_for.items(
        )  # node_to.dict_ask_for is dict
        dict_ask_for.sort(key=lambda x: x[0])  # sort by key(time:int64)
        for time, invs in dict_ask_for:
            if time > now:
                break
            for inv in invs:
                print("sending getdata: %s" % str(inv))
                if not already_have(txdb, inv):
                    list_ask_for.append(inv)
            node_to.dict_ask_for.pop(time, None)
        if list_ask_for:
            node_to.push_message(base.COMMAND_GETDATA,
                                 list_ask_for,
                                 ignore=ignore)

        txdb.close()
        pass  # end end critical
    return True
Esempio n. 9
0
def bitcoin_miner(t):
    """

    :param t:
    :type t: ExitedThread
    :return:
    """
    print "Miner started"
    # TODO add thread priority  THREAD_PRIORITY_LOWEST
    key = Key.PyKey()
    key.make_new_key()

    extra_nonce = 0
    while ctx.fGenerateCoins:
        timeutil.sleep_msec(50)  # 50 ms
        t.check_self_shutdown()
        if t.exit:
            break
        # while len(ctx.listNodes) == 0:
        #     timeutil.sleep_msec(1000)
        #     t.check_self_shutdown()
        #     if t.exit:
        #         return True

        transactions_updated_last = ctx.transactionsUpdated
        index_prev = ctx.indexBest
        bits = Block.get_next_work_required(index_prev)

        # create coinbase tx
        tx_new = Tx.PyTransaction()
        tx_in = Tx.PyTxIn()
        tx_in.prev_out.set_null()
        extra_nonce += 1
        tx_in.script_sig.append(bits).append(extra_nonce)
        tx_new.l_in.append(tx_in)
        tx_out = Tx.PyTxOut()
        tx_out.script_pubkey.extend(key.get_pubkey()).append(
            Script.OpCodeType.OP_CHECKSIG)
        tx_new.l_out.append(tx_out)

        # create new block
        block = Block.PyBlock()

        # Add our coinbase tx as first transaction
        block.l_tx.append(tx_new)

        # Collect the latest transactions into the block
        fees = 0
        with ctx.mainLock:
            with ctx.dictTransactionsLock:
                txdb = Tx.PyTxDB("r")
                test_pool = dict()  # map<uint256, PyTxIndex>
                flag_already_added = [False] * len(ctx.dictTransactions)
                found_something = True
                block_size = 0
                while found_something and block_size < cfg.MAX_SIZE / 2:  # block_size < 2MB/2 = 1MB
                    found_something = False
                    n = 0
                    for tx_hash, tx in ctx.dictTransactions.iteritems():
                        if flag_already_added[n]:
                            continue
                        if tx.is_coinbase() or not tx.is_final():
                            continue
                        # Transaction fee requirements, mainly only needed for flood control
                        # Under 10K (about 80 inputs) is free for first 100 transactions
                        # Base rate is 0.01 per KB
                        min_fee = tx.get_min_fee(
                            len(block.l_tx) < 100)  # 100 个交易内的打折,之后的不打折
                        tmp_test_pool = copy.deepcopy(
                            test_pool)  # 防止下面执行出错对test_pool产生干扰
                        ret = tx.connect_inputs(txdb, tmp_test_pool,
                                                Tx.PyDiskTxPos(1, 1, 1), 0,
                                                False, True, min_fee)
                        if ret is None:
                            continue
                        fees += ret  # 累积交易费
                        test_pool = tmp_test_pool

                        block.l_tx.append(tx)
                        block_size += tx.serialize_size(
                            serialize.SerType.SER_NETWORK)
                        flag_already_added[n] = True
                        found_something = True  # 这是为了跳出外层 while
                        n += 1
                        # end for
                        pass
                    pass  # end while
                txdb.close()
                pass
        # end critical_block
        pass
        block.bits = bits
        block.l_tx[0].l_out[0].value = block.get_block_value(fees)
        print("\n\nRunning Miner with %d transactions in block" %
              len(block.l_tx))

        # Prebuild hash buffer
        class Unnamed1(serialize.Serializable):
            class Unnamed2(serialize.Serializable):
                def __init__(self):
                    self.version = 0
                    self.hash_prev_block = 0
                    self.hash_merkle_root = 0
                    self.time = 0
                    self.bits = 0
                    self.nonce = 0

                def serialize(self, nType=0, nVersion=cfg.VERSION):
                    s = b''
                    s += serialize.ser_int(self.version)
                    s += serialize.ser_uint256(self.hash_prev_block)
                    s += serialize.ser_uint256(self.hash_merkle_root)
                    s += serialize.ser_uint(self.time)
                    s += serialize.ser_uint(self.bits)
                    s += serialize.ser_uint(self.nonce)
                    return s

            def __init__(self):
                self.block = Unnamed1.Unnamed2()
                self.padding0 = ['\x00'] * 64
                self.hash1 = 0
                self.padding1 = ['\x00'] * 64

        tmp = Unnamed1()
        tmp.block.version = block.version
        tmp.block.hash_prev_block = block.hash_prev_block = (
            index_prev.get_block_hash() if index_prev else 0)
        tmp.block.hash_merkle_root = block.hash_merkle_root = block.build_merkle_tree(
        )
        tmp.block.time = block.time = max(
            (index_prev.get_median_time_past() + 1 if index_prev else 0),
            timeutil.get_adjusted_time())
        tmp.block.bits = block.bits = bits  # difficulty
        tmp.block.nonce = block.nonce = 1  # 从1 开始计算

        # blocks0 = format_hash_blocks(tmp.block.serialize(), tmp.padding0)
        # blocks1 = format_hash_blocks(serialize.ser_uint256(tmp.hash1), tmp.padding1)

        # search
        start = timeutil.get_time()
        block_hash = 0
        hash_target = BN.PyBigNum.set_compact(block.bits).get_uint256()

        while True:
            if t.exit:
                break
            # use local sha256
            block_hash = cryptoutil.Hash(tmp.block.serialize())

            if block_hash <= hash_target:
                block.nonce = tmp.block.nonce
                assert block_hash == block.get_hash()
                # debug print
                print("Miner:")
                print("proof-of-work found  \n  hash: %s  \ntarget: %s\n" %
                      (serialize.hexser_uint256(block_hash),
                       serialize.hexser_uint256(hash_target)))
                print str(block)

                # TODO  setthreadpriority  THREAD_PRIORITY_NORMAL
                with ctx.mainLock:
                    # save key
                    kaction.add_key(key)

                    key.make_new_key()
                    # Process this block the same as if we had received it from another node
                    if not blkaction.process_block(None, block):
                        print(
                            "ERROR in CoinMiner, ProcessBlock, block not accepted"
                        )
                    else:
                        print("miner a block, waiting for relay")

                # TODO ADD THREAD_PRIORITY_LOWEST
                timeutil.sleep_msec(500)
                break

            # Update nTime every few seconds
            tmp.block.nonce += 1
            if tmp.block.nonce & 0x3FFFF == 0:
                # checkforshutdown
                if tmp.block.nonce == 0:
                    break
                if id(index_prev) != id(ctx.indexBest):
                    break
                if ctx.transactionsUpdated != transactions_updated_last and (
                        timeutil.get_time() - start > 60):
                    break
                if not ctx.fGenerateCoins:
                    break
                tmp.block.time = block.time = max(
                    (index_prev.get_median_time_past() + 1),
                    timeutil.get_adjusted_time())
            pass  # end nonce loop
        pass  # end whole loop
    return True