mirror of
https://github.com/aljazceru/python-teos.git
synced 2025-12-18 14:44:21 +01:00
pisa-btc initial commit
Contains basic structure, zmq so subscribe to blockid messages, api and so on. Still WIP
This commit is contained in:
18
.gitignore
vendored
Normal file
18
.gitignore
vendored
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
*~
|
||||||
|
\#*\#
|
||||||
|
.\#*
|
||||||
|
build/
|
||||||
|
dist/
|
||||||
|
node_modules/
|
||||||
|
.vscode/
|
||||||
|
*.log
|
||||||
|
.nyc_output
|
||||||
|
logs/
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
.idea
|
||||||
|
conf.py
|
||||||
|
bitcoin.conf
|
||||||
|
__pycache__/*
|
||||||
|
.pending*
|
||||||
|
|
||||||
2
pisa-btc/apps/__init__.py
Normal file
2
pisa-btc/apps/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
PISA_API_SERVER = 'localhost'
|
||||||
|
PISA_API_PORT = 2222
|
||||||
1
pisa-btc/apps/messages.py
Normal file
1
pisa-btc/apps/messages.py
Normal file
@@ -0,0 +1 @@
|
|||||||
|
wrong_txid = "You should provide the 16 MSB (in base58 hex) of the txid you'd like to be monitored."
|
||||||
53
pisa-btc/apps/pisa-cli.py
Normal file
53
pisa-btc/apps/pisa-cli.py
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
from multiprocessing.connection import Client
|
||||||
|
from getopt import getopt
|
||||||
|
from sys import argv
|
||||||
|
from apps import PISA_API_SERVER, PISA_API_PORT
|
||||||
|
import apps.messages as msg
|
||||||
|
from base58 import b58decode
|
||||||
|
|
||||||
|
|
||||||
|
commands = ['register_tx']
|
||||||
|
|
||||||
|
|
||||||
|
def check_txid_format(txid):
|
||||||
|
if len(txid) != 32:
|
||||||
|
raise Exception("txid does not matches the expected size (16-byte / 32 hex chars). " + msg.wrong_txid)
|
||||||
|
try:
|
||||||
|
b58decode(txid)
|
||||||
|
except ValueError:
|
||||||
|
raise Exception("The provided txid is not in base58. " + msg.wrong_txid)
|
||||||
|
|
||||||
|
|
||||||
|
def show_usage():
|
||||||
|
print("usage: python pisa-cli.py argument [additional_arguments]."
|
||||||
|
"\nArguments:"
|
||||||
|
"\nregister_tx half_txid: \tregisters a txid to be monitored by PISA using the 16 MSB of the txid (in hex)."
|
||||||
|
"\nhelp: \t\tshows this message.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
opts, args = getopt(argv[1:], '', commands)
|
||||||
|
|
||||||
|
# Get args
|
||||||
|
if len(args) > 0:
|
||||||
|
command = args[0]
|
||||||
|
else:
|
||||||
|
raise Exception("Argument missing. Use help for usage information.")
|
||||||
|
|
||||||
|
if command in commands:
|
||||||
|
|
||||||
|
if command == 'register_tx':
|
||||||
|
if len(args) != 2:
|
||||||
|
raise Exception("txid missing. " + msg.wrong_txid)
|
||||||
|
|
||||||
|
arg = args[1]
|
||||||
|
check_txid_format(arg)
|
||||||
|
|
||||||
|
conn = Client((PISA_API_SERVER, PISA_API_PORT))
|
||||||
|
|
||||||
|
# Argv could be undefined, but we only have one command for now so safe
|
||||||
|
conn.send((command, arg))
|
||||||
|
|
||||||
|
else:
|
||||||
|
show_usage()
|
||||||
|
|
||||||
2
pisa-btc/pisa/__init__.py
Normal file
2
pisa-btc/pisa/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
HOST = 'localhost'
|
||||||
|
PORT = 2222
|
||||||
34
pisa-btc/pisa/api.py
Normal file
34
pisa-btc/pisa/api.py
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
import threading
|
||||||
|
from multiprocessing.connection import Listener
|
||||||
|
from pisa import *
|
||||||
|
|
||||||
|
|
||||||
|
def manage_api(debug, host=HOST, port=PORT):
|
||||||
|
listener = Listener((host, port))
|
||||||
|
while True:
|
||||||
|
conn = listener.accept()
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
print('Connection accepted from', listener.last_accepted)
|
||||||
|
|
||||||
|
# Maintain metadata up to date.
|
||||||
|
t_serve = threading.Thread(target=serve_data, args=[debug, conn, listener.last_accepted])
|
||||||
|
t_serve.start()
|
||||||
|
|
||||||
|
|
||||||
|
def serve_data(debug, conn, remote_addr):
|
||||||
|
while not conn.closed:
|
||||||
|
try:
|
||||||
|
msg = conn.recv()
|
||||||
|
|
||||||
|
if type(msg) == tuple:
|
||||||
|
if len(msg) is 2:
|
||||||
|
command, arg = msg
|
||||||
|
|
||||||
|
print(command, arg)
|
||||||
|
|
||||||
|
except (IOError, EOFError):
|
||||||
|
if debug:
|
||||||
|
print('Disconnecting from', remote_addr)
|
||||||
|
|
||||||
|
conn.close()
|
||||||
25
pisa-btc/pisa/pisad.py
Normal file
25
pisa-btc/pisa/pisad.py
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
from getopt import getopt
|
||||||
|
from sys import argv
|
||||||
|
from threading import Thread
|
||||||
|
from pisa import shared
|
||||||
|
from pisa.zmq_subscriber import run_subscribe
|
||||||
|
from pisa.tx_watcher import watch_txs
|
||||||
|
from pisa.api import manage_api
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
debug = False
|
||||||
|
opts, _ = getopt(argv[1:], 'd', ['debug'])
|
||||||
|
for opt, arg in opts:
|
||||||
|
if opt in ['-d', '--debug']:
|
||||||
|
debug = True
|
||||||
|
|
||||||
|
shared.init()
|
||||||
|
|
||||||
|
zmq_thread = Thread(target=run_subscribe, args=[debug])
|
||||||
|
tx_watcher_thread = Thread(target=watch_txs, args=[debug])
|
||||||
|
api_thread = Thread(target=manage_api, args=[debug])
|
||||||
|
|
||||||
|
zmq_thread.start()
|
||||||
|
tx_watcher_thread.start()
|
||||||
|
api_thread.start()
|
||||||
8
pisa-btc/pisa/shared.py
Normal file
8
pisa-btc/pisa/shared.py
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
from queue import Queue
|
||||||
|
|
||||||
|
|
||||||
|
def init():
|
||||||
|
global block_queue, registered_txs
|
||||||
|
|
||||||
|
block_queue = Queue()
|
||||||
|
registered_txs = dict()
|
||||||
23
pisa-btc/pisa/tx_watcher.py
Normal file
23
pisa-btc/pisa/tx_watcher.py
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
from pisa import shared
|
||||||
|
from bitcoinrpc.authproxy import AuthServiceProxy, JSONRPCException
|
||||||
|
from conf import BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT
|
||||||
|
|
||||||
|
|
||||||
|
def watch_txs(debug):
|
||||||
|
bitcoin_cli = AuthServiceProxy("http://%s:%s@%s:%d" % (BTC_RPC_USER, BTC_RPC_PASSWD, BTC_RPC_HOST, BTC_RPC_PORT))
|
||||||
|
|
||||||
|
while True:
|
||||||
|
block_hash = shared.block_queue.get()
|
||||||
|
|
||||||
|
try:
|
||||||
|
block = bitcoin_cli.getblock(block_hash)
|
||||||
|
|
||||||
|
prev_tx_id = block.get('previousblockhash')
|
||||||
|
txs = block.get('tx')
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
# Log shit
|
||||||
|
print(prev_tx_id, txs)
|
||||||
|
|
||||||
|
except JSONRPCException as e:
|
||||||
|
print(e)
|
||||||
37
pisa-btc/pisa/zmq_subscriber.py
Normal file
37
pisa-btc/pisa/zmq_subscriber.py
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
"""
|
||||||
|
Adapted from https://github.com/bitcoin/bitcoin/blob/master/contrib/zmq/zmq_sub.py
|
||||||
|
"""
|
||||||
|
|
||||||
|
import binascii
|
||||||
|
import zmq
|
||||||
|
import conf
|
||||||
|
from pisa import shared
|
||||||
|
|
||||||
|
|
||||||
|
class ZMQHandler:
|
||||||
|
def __init__(self):
|
||||||
|
self.zmqContext = zmq.Context()
|
||||||
|
|
||||||
|
self.zmqSubSocket = self.zmqContext.socket(zmq.SUB)
|
||||||
|
self.zmqSubSocket.setsockopt(zmq.RCVHWM, 0)
|
||||||
|
self.zmqSubSocket.setsockopt_string(zmq.SUBSCRIBE, "hashblock")
|
||||||
|
|
||||||
|
self.zmqSubSocket.connect("%s://%s:%s" % (conf.FEED_PROTOCOL, conf.FEED_ADDR, conf.FEED_PORT))
|
||||||
|
|
||||||
|
def handle(self, debug):
|
||||||
|
msg = self.zmqSubSocket.recv_multipart()
|
||||||
|
topic = msg[0]
|
||||||
|
body = msg[1]
|
||||||
|
|
||||||
|
if topic == b"hashblock":
|
||||||
|
block_hash = binascii.hexlify(body).decode('UTF-8')
|
||||||
|
shared.block_queue.put(block_hash)
|
||||||
|
|
||||||
|
if debug:
|
||||||
|
# Log shit
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def run_subscribe(debug):
|
||||||
|
daemon = ZMQHandler()
|
||||||
|
daemon.handle(debug)
|
||||||
11
pisa-btc/sample_conf.py
Normal file
11
pisa-btc/sample_conf.py
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
# bitcoind
|
||||||
|
BTC_RPC_USER = None
|
||||||
|
BTC_RPC_PASSWD = None
|
||||||
|
BTC_RPC_HOST = None
|
||||||
|
BTC_RPC_PORT = None
|
||||||
|
|
||||||
|
|
||||||
|
# ZMQ
|
||||||
|
FEED_PROTOCOL = None
|
||||||
|
FEED_ADDR = None
|
||||||
|
FEED_PORT = None
|
||||||
Reference in New Issue
Block a user