Skip to content
Snippets Groups Projects
Select Git revision
  • feature/protocol-v2s
  • master default
  • 0016_checksum
  • tx_comment_encrypt
  • dubp_v13
  • hd_wallet
  • dubp-mnemonic
  • ws2p_v2
  • dubp_v12
  • tx-out-hash
10 results

0004_ws2p_v1.md

Blame
  • utils.py 4.46 KiB
    #!/usr/bin/env python3
    """
    	This file is part of ĞMixer-py.
    
    	ĞMixer-py is free software: you can redistribute it and/or modify
    	it under the terms of the GNU Affero General Public License as published by
    	the Free Software Foundation, either version 3 of the License, or
    	(at your option) any later version.
    
    	ĞMixer-py is distributed in the hope that it will be useful,
    	but WITHOUT ANY WARRANTY; without even the implied warranty of
    	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    	GNU Affero General Public License for more details.
    
    	You should have received a copy of the GNU Affero General Public License
    	along with ĞMixer-py.  If not, see <https://www.gnu.org/licenses/>.
    """
    
    import sys, os, re, socket, time
    import socks
    from duniterpy.key import SigningKey, PublicKey
    _argv = sys.argv # silkaj reads sys.argv!
    sys.argv = []
    import silkaj.money, silkaj.tx, silkaj.auth
    sys.argv = _argv
    
    
    #-------- DATA
    
    # Decode binary int (Big Endian)
    def bin_to_int(b):
    	return sum([b[i]*256**i for i in range(len(b))])
    
    # Encode int into bin (Big Endian)
    # n: number ; b: bytes
    def int_to_bin(n, b=4):
    	return bytes([(n>>(i*8))&255 for i in range(b)])
    
    # Set fixed length 44
    def normalize_pubkey(pubkey):
    	return pubkey + " "*(44-len(pubkey))
    
    # Set original length (43 or 44)
    def clean_pubkey(pubkey):
    	return pubkey.replace(" ", "")
    
    
    #-------- NETWORK
    
    RECBUF = 1024
    
    p_clen = re.compile("\r?\ncontent-length: *(\d+)\r?\n?", re.IGNORECASE)
    
    def sdata(host, mode, url="/", data=b"", uagent="GMixer-py", proxy=None, proxy_onion_only=False):
    	tsocket = socket.socket
    	if proxy and (not proxy_onion_only or re.match("^.+\.onion$", host[0])):
    		socks.set_default_proxy(socks.PROXY_TYPE_SOCKS5, proxy[0], proxy[1])
    		tsocket = socks.socksocket
    	if ":" in host[0]: # IPv6
    		sock = tsocket(socket.AF_INET6, socket.SOCK_STREAM)
    	else: # IPv4
    		sock = tsocket(socket.AF_INET, socket.SOCK_STREAM)
    	sock.connect(host)
    	
    	raw = (mode+" "+url+" HTTP/1.1\r\nHost: "+host[0]+":"+str(host[1])+"\r\nUser-Agent: "+uagent+"\r\nAccept: */*\r\nContent-Length: "+str(len(data))+"\r\n\r\n").encode()+data
    	sock.sendall(raw)
    	
    	paquet = b""
    	header = b""
    	content = b""
    	content_len = 0
    	resp = {}
    	lf = 0
    	while True:
    		raw = sock.recv(RECBUF)
    		if raw:
    			paquet += raw
    			if lf >= 0:
    				for c in raw:
    					if c == 10:# LF
    						lf += 1
    					elif c != 13:# CR
    						lf = 0
    					if lf > 1:
    						parts = paquet.split(b"\r\n\r\n")
    						header = parts[0]
    						content = parts[1]
    						try:
    							content_len = int(p_clen.search(header.decode()).group(1))
    						except AttributeError:
    							content_len = 0
    						break
    				if lf > 1:
    					break
    		else:
    			break
    	while len(content) < content_len:
    		raw = sock.recv(RECBUF)
    		paquet += raw
    		content += raw
    	
    	return header, content
    
    #-------- CONSOLE
    
    LOG_INFO = 1
    LOG_TRACE = 2
    LOG_WARN = 3
    LOG_ERROR = 4
    LOGMSG_TYPES = {LOG_INFO:"\033[96minfo\033[0m", LOG_TRACE:"\033[39mtrace\033[0m", LOG_WARN:"\033[93mwarn\033[0m", LOG_ERROR:"\033[91merror\033[0m"}
    
    def logPrint(msg, msgtype):
    	print(time.strftime("%Y-%m-%d %H:%M:%S")+" ["+LOGMSG_TYPES[msgtype]+"] "+msg)
    
    def getargv(arg, default="", n=1, args=sys.argv):
    	if arg in args and len(args) > args.index(arg)+n:
    		return args[args.index(arg)+n]
    	else:
    		return default
    
    
    #-------- ĞMixer
    
    class Peer:
    	def __init__(self, pubkey, host, port, up):
    		self.pubkey = pubkey
    		self.host = host
    		self.port = int(port)
    		self.up = up
    		
    		self.keys = PublicKey(pubkey)
    	
    	def __str__(self):
    		return self.pubkey[:8] + "@" + self.host + ":" + str(self.port)
    	
    	def export_str(self):
    		return self.pubkey + " " + self.host + " " + str(self.port)
    
    # Read peers list
    def readPeers(dir):
    	if not os.path.isfile(dir+"/peers"):
    		open(dir+"/peers", "w").close()
    	
    	peers = []
    	peers_index = {}
    	peersfile = open(dir+"/peers", "r")
    	while True:
    		line = peersfile.readline()
    		if len(line) <= 1:
    			break
    		else:
    			cols = line.replace("\n", "").split(" ")
    			peer = Peer(cols[0], cols[1], cols[2], None)
    			peers.append(peer)
    			peers_index[peer.pubkey] = peer
    	peersfile.close()
    	return peers, peers_index
    
    # Save peers list
    def writePeers(dir, peers):
    	peersfile = open(dir+"/peers", "w")
    	for peer in peers:
    		peersfile.write(peer.export_str()+"\n")
    	peersfile.close()
    
    def sendTransaction(sender_keys, receiver_pubkey, amount, comment):
    	sender_amount = silkaj.money.get_amount_from_pubkey(sender_keys.pubkey)[0]
    	assert sender_amount >= amount
    	
    	silkaj.tx.generate_and_send_transaction(sender_keys.hex_seed().decode(), sender_keys.pubkey, amount, [receiver_pubkey], comment)