Skip to content

Commit

Permalink
Various stability fixes and removal of some fields (#19)
Browse files Browse the repository at this point in the history
  • Loading branch information
bboerst authored Nov 3, 2024
1 parent f8a36e2 commit 2e96158
Show file tree
Hide file tree
Showing 9 changed files with 58 additions and 185 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

helm-charts/values*_collector.yaml
*.pyc
.aider*
4 changes: 2 additions & 2 deletions helm-charts/stratum-work-collector/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
apiVersion: v2
name: stratum-work-collector
description: A Helm chart for deploying the Pool Work Collector Python script
version: 0.1.2
appVersion: v1.0.3
version: 0.1.6
appVersion: v1.0.6
4 changes: 2 additions & 2 deletions helm-charts/stratum-work-webapp/Chart.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
apiVersion: v2
description: Web frontend/backend for Pool Work
name: stratum-work-webapp
version: 0.1.3
version: 0.1.6
# renovate: image=bboerst/stratum-work-webapp
appVersion: "v1.0.3"
appVersion: "v1.0.6"
6 changes: 3 additions & 3 deletions helm-charts/stratum-work-webapp/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: {{ template "stratum-work-webapp.name" . }}
app: {{ template "stratum-work-webapp.fullname" . }}
chart: {{ template "stratum-work-webapp.chart" . }}
heritage: {{ .Release.Service }}
{{ .Values.componentLabelKeyOverride | default "app.kubernetes.io/component" }}: stratum-work-webapp
Expand All @@ -21,7 +21,7 @@ spec:
{{- end }}
selector:
matchLabels:
app: {{ template "stratum-work-webapp.name" . }}
app: {{ template "stratum-work-webapp.fullname" . }}
{{- if .Values.useComponentLabel }}
{{ .Values.componentLabelKeyOverride | default "app.kubernetes.io/component" }}: stratum-work-webapp
{{- end }}
Expand All @@ -37,7 +37,7 @@ spec:
{{- end }}
{{- end }}
labels:
app: {{ template "stratum-work-webapp.name" . }}
app: {{ template "stratum-work-webapp.fullname" . }}
component: "{{ .Values.name }}"
{{ .Values.componentLabelKeyOverride | default "app.kubernetes.io/component" }}: stratum-work-webapp
{{- if .Values.podLabels }}
Expand Down
4 changes: 2 additions & 2 deletions helm-charts/stratum-work-webapp/templates/service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ metadata:
{{- if .Values.service.labels }}
{{ toYaml .Values.service.labels | indent 4 }}
{{- end }}
app: {{ template "stratum-work-webapp.name" . }}
app: {{ template "stratum-work-webapp.fullname" . }}
chart: {{ template "stratum-work-webapp.chart" . }}
component: "{{ .Values.name }}"
heritage: {{ .Release.Service }}
Expand Down Expand Up @@ -50,6 +50,6 @@ spec:
protocol: TCP
targetPort: "flask"
selector:
app: {{ template "stratum-work-webapp.name" . }}
app: {{ template "stratum-work-webapp.fullname" . }}
type: "{{ .Values.service.type }}"
{{- end }}
1 change: 1 addition & 0 deletions helm-charts/stratum-work-webapp/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ env:
MONGODB_USERNAME: "mongoadmin"
MONGODB_PASSWORD: "hunter1"
MONGODB_HOSTS: "mongodb-0.mongodb-svc.mongodb.svc.cluster.local:27017,mongodb-1.mongodb-svc.mongodb.svc.cluster.local:27017/"
CORS_ORIGINS: "http://127.0.0.1:8000,http://localhost:8000"

arguments: []

Expand Down
127 changes: 45 additions & 82 deletions webapp/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,18 @@
import os
import pika

# Get CORS origins from environment variable
CORS_ORIGINS = os.environ.get('CORS_ORIGINS', 'http://127.0.0.1:8000,http://localhost:8000').split(',')

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": ["http://127.0.0.1:8000", "http://localhost:8000", "https://poolwork.live", "https://stratum.work"]}})
socketio = SocketIO(app, cors_allowed_origins=["http://127.0.0.1:8000", "http://localhost:8000", "https://poolwork.live", "https://stratum.work"])
CORS(app, resources={r"/*": {"origins": CORS_ORIGINS}})
socketio = SocketIO(app, cors_allowed_origins=CORS_ORIGINS)

@app.after_request
def add_headers(response):
response.headers['Access-Control-Allow-Origin'] = 'https://stratum.work'
origin = request.headers.get('Origin')
if origin in CORS_ORIGINS:
response.headers['Access-Control-Allow-Origin'] = origin
return response

connection = None
Expand All @@ -47,17 +52,6 @@ def add_headers(response):
rabbitmq_exchange = os.environ.get('RABBITMQ_EXCHANGE')

def process_row_data(row):
if 'counters' not in globals():
globals()['counters'] = {}

pool_name = row['pool_name']
if pool_name not in counters or counters[pool_name]['height'] != row['height']:
counters[pool_name] = {'height': row['height'], 'count': 1}
else:
counters[pool_name]['count'] += 1

template_revision = counters[pool_name]['count']

coinbase1 = row['coinbase1']
coinbase2 = row['coinbase2']
extranonce1 = row['extranonce1']
Expand All @@ -84,19 +78,10 @@ def process_row_data(row):
value = tx_out.coin_value / 1e8
coinbase_outputs.append({"address": address, "value": value})

current_time = time.time()
if 'last_revision_time' not in counters[pool_name]:
counters[pool_name]['last_revision_time'] = current_time
time_since_last_revision = 0
else:
time_since_last_revision = current_time - counters[pool_name]['last_revision_time']
counters[pool_name]['last_revision_time'] = current_time

processed_row = {
'pool_name': row['pool_name'],
'timestamp': row['timestamp'],
'height': height,
'template_revision': template_revision,
'prev_block_hash': prev_block_hash,
'block_version': block_version,
'coinbase_raw': coinbase_hex,
Expand All @@ -110,8 +95,7 @@ def process_row_data(row):
'merkle_branches': merkle_branches,
'merkle_branch_colors': merkle_branch_colors,
'coinbase_output_value': output_value,
'coinbase_outputs': coinbase_outputs,
'time_since_last_revision': time_since_last_revision
'coinbase_outputs': coinbase_outputs
}

return processed_row
Expand Down Expand Up @@ -168,7 +152,7 @@ def get_transaction_fee_rate(first_transaction):
def extract_coinbase_script_ascii(coinbase_tx):
# Get the script_sig in hex from the input of the coinbase transaction
script_sig_hex = coinbase_tx.txs_in[0].script.hex()

# Remove the first 8 characters (4 bytes) which represent the block height
script_sig_hex = script_sig_hex[8:]

Expand All @@ -188,72 +172,52 @@ def precompute_merkle_branch_colors(merkle_branches):
def hash_code(text):
return sum(ord(char) for char in text)

def initialize_queue_connection():
def consume_messages():
global connection, channel
try:
credentials = pika.PlainCredentials(rabbitmq_username, rabbitmq_password)
connection = pika.BlockingConnection(pika.ConnectionParameters(rabbitmq_host, rabbitmq_port, '/', credentials))
channel = connection.channel()

# Declare the exchange as a fanout exchange
channel.exchange_declare(exchange=rabbitmq_exchange, exchange_type='fanout', durable=True)
credentials = pika.PlainCredentials(rabbitmq_username, rabbitmq_password)
connection = pika.BlockingConnection(pika.ConnectionParameters(rabbitmq_host, rabbitmq_port, '/', credentials))
channel = connection.channel()

# Let RabbitMQ generate a unique queue name for each consumer
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
# Declare the exchange as a fanout exchange
channel.exchange_declare(exchange=rabbitmq_exchange, exchange_type='fanout', durable=True)

# Bind the generated queue to the fanout exchange
channel.queue_bind(exchange=rabbitmq_exchange, queue=queue_name)
# Let RabbitMQ generate a unique queue name for each consumer
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue

logger.info('RabbitMQ connection initialized')
return queue_name
except Exception as e:
logger.exception(f"Error initializing RabbitMQ connection: {e}")
return None
# Bind the generated queue to the fanout exchange
channel.queue_bind(exchange=rabbitmq_exchange, queue=queue_name)

def consume_messages(queue_name):
try:
def callback(ch, method, properties, body):
try:
message = json.loads(body)
processed_message = process_row_data(message)
socketio.emit('mining_data', processed_message, to=None)
except Exception as e:
logger.exception(f"Error processing message: {e}")

channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)
logger.info('Started consuming messages from the exchange')
channel.start_consuming()
except Exception as e:
logger.exception(f"Error in consume_messages: {e}")

# Initialize queue connection
queue_name = initialize_queue_connection()
if queue_name:
# Start consuming messages in a background thread
socketio.start_background_task(target=consume_messages, queue_name=queue_name)
def callback(ch, method, properties, body):
try:
message = json.loads(body)
processed_message = process_row_data(message)
for client_id in connected_clients:
socketio.emit('mining_data', processed_message, room=client_id)
except Exception as e:
logger.exception(f"Error processing message: {e}")

channel.basic_consume(queue=queue_name, on_message_callback=callback, auto_ack=True)

logger.info('Started consuming messages from the exchange')
channel.start_consuming()

@socketio.on('connect')
def handle_connect():
try:
logger.info('Client connected')
connected_clients.add(request.sid)
except Exception as e:
logger.warning(f"Error during client connect: {e}")
logger.info('Client connected')
if len(connected_clients) == 0:
socketio.start_background_task(target=consume_messages)
connected_clients.add(request.sid)

@socketio.on('disconnect')
def handle_disconnect():
try:
logger.info('Client disconnected')
connected_clients.remove(request.sid)
except KeyError:
logger.info('Client disconnected (already removed)')
except Exception as e:
logger.warning(f"Error during client disconnect: {e}")

@socketio.on('heartbeat')
def handle_heartbeat():
pass # Simply acknowledge the heartbeat
logger.info('Client disconnected')
connected_clients.remove(request.sid)
if len(connected_clients) == 0:
if channel and connection:
channel.stop_consuming()
connection.close()

def gzip_response(response):
accept_encoding = request.headers.get('Accept-Encoding', '')
Expand Down Expand Up @@ -294,5 +258,4 @@ def handle_sigterm(*args):
sys.exit(0)

if __name__ == "__main__":
signal.signal(signal.SIGTERM, handle_sigterm)
socketio.run(app, debug=True, use_reloader=False)
socketio.run(app)
85 changes: 2 additions & 83 deletions webapp/static/main.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,5 @@
document.addEventListener('DOMContentLoaded', () => {
function connectWebSocket() {
const socket = io(SOCKET_URL, {
reconnection: true,
reconnectionAttempts: Infinity,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
randomizationFactor: 0.5,
});

socket.on('connect', () => {
console.log('WebSocket connected');
hideReconnectionMessage();
});

socket.on('disconnect', (reason) => {
console.log('WebSocket disconnected:', reason);
showReconnectionMessage();
});

socket.on('connect_error', (error) => {
console.error('WebSocket connection error:', error);
showReconnectionMessage();
});

return socket;
}

function showReconnectionMessage() {
const message = document.getElementById('reconnection-message');
if (!message) {
const newMessage = document.createElement('div');
newMessage.id = 'reconnection-message';
newMessage.innerHTML = 'Attempting to reconnect...';
newMessage.style.position = 'fixed';
newMessage.style.top = '10px';
newMessage.style.right = '10px';
newMessage.style.backgroundColor = 'rgba(255, 0, 0, 0.7)';
newMessage.style.color = 'white';
newMessage.style.padding = '10px';
newMessage.style.borderRadius = '5px';
newMessage.style.zIndex = '1000';
document.body.appendChild(newMessage);
}
}

function hideReconnectionMessage() {
const message = document.getElementById('reconnection-message');
if (message) {
message.remove();
}
}

const socket = connectWebSocket();
const socket = io(SOCKET_URL);
let isPaused = false;

const pauseButton = document.getElementById('pause-button');
Expand Down Expand Up @@ -104,27 +52,6 @@ document.addEventListener('DOMContentLoaded', () => {
field: 'pool_name',
width: 130,
},
{
title: 'Template Revision for Current Block',
field: 'template_revision',
width: 50,
sorter: 'number',
visible: true,
},
{
title: 'Time Since Last Template Revision',
field: 'time_since_last_revision',
width: 80,
sorter: 'number',
formatter: function(cell) {
const value = cell.getValue();
if (value === undefined || value === null) return '';
const seconds = Math.floor(value);
const milliseconds = Math.round((value - seconds) * 1000);
return `${seconds}.${milliseconds.toString().padStart(3, '0')}s`;
},
visible: true,
},
{
title: '<!--<a href="https://github.com/bboerst/stratum-work/blob/main/docs/timestamp.md" target="_blank"><i class="fas fa-question-circle"></i></a><br /> -->Timestamp',
field: 'timestamp',
Expand Down Expand Up @@ -154,6 +81,7 @@ document.addEventListener('DOMContentLoaded', () => {
.filter(output => !output.address.includes("nulldata"))
.map(output => `${output.address}:${output.value}`)
.join('|');

const color = generateColorFromOutputs(outputs);
cell.getElement().style.backgroundColor = color;
cell.getElement().style.whiteSpace = 'nowrap';
Expand Down Expand Up @@ -371,13 +299,4 @@ document.addEventListener('DOMContentLoaded', () => {
return text.split('').reduce((prevHash, currVal) =>
(((prevHash << 5) - prevHash) + currVal.charCodeAt(0))|0, 0);
}

setInterval(() => {
if (socket.connected) {
socket.emit('heartbeat');
} else {
console.log('WebSocket not connected, attempting to reconnect...');
socket.connect();
}
}, 30000); // Send heartbeat every 30 seconds
});
11 changes: 0 additions & 11 deletions webapp/templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -233,17 +233,6 @@
animation: flash-border 1s infinite;
border: 2px solid red;
}

#reconnection-message {
position: fixed;
top: 10px;
right: 10px;
background-color: rgba(255, 0, 0, 0.7);
color: white;
padding: 10px;
border-radius: 5px;
z-index: 1000;
}
</style>
</head>

Expand Down

0 comments on commit 2e96158

Please sign in to comment.