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
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))
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
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
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
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
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
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
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