latest fixes

This commit is contained in:
Dobromir Popov
2025-09-05 00:10:46 +03:00
parent 1bcf7109cf
commit fec5f35cce

View File

@@ -14,7 +14,7 @@ import struct
from requests.auth import HTTPBasicAuth
class RinCoinStratumProxy:
def __init__(self, stratum_host='0.0.0.0', stratum_port=3333,
def __init__(self, stratum_host='0.0.0.0', stratum_port=3334,
rpc_host='127.0.0.1', rpc_port=9556,
rpc_user='rinrpc', rpc_password='745ce784d5d537fc06105a1b935b7657903cfc71a5fb3b90',
target_address='rin1qahvvv9d5f3443wtckeqavwp9950wacxfmwv20q'):
@@ -80,18 +80,28 @@ class RinCoinStratumProxy:
return b"\xff" + struct.pack('<Q', n)
def decode_bech32_address(self, address):
"""Minimal bech32 decoder for witness addresses"""
"""Decode RinCoin bech32 address to script"""
try:
# Simplified bech32 decoder - for production use proper library
if not address.startswith('rin1'):
raise ValueError("Not a RinCoin bech32 address")
# For now, return a placeholder P2WPKH script
# In production, implement full bech32 decoding
return bytes([0x00, 0x14]) + b'\x00' * 20 # OP_0 + 20-byte placeholder
# Use generatetoaddress to get a proper script for this address
# This ensures we create valid outputs that can actually be spent
result = self.rpc_call("validateaddress", [address])
if result and result.get('isvalid') and 'scriptPubKey' in result:
script_hex = result['scriptPubKey']
return bytes.fromhex(script_hex)
else:
# Fallback: create a basic P2WPKH script if RPC validation fails
# Extract the witness program (assuming it's standard 20-byte)
# This is a simplified approach - in production use a proper bech32 library
print(f"Warning: Using fallback script for {address}")
return bytes([0x00, 0x14]) + bytes(20) # OP_0 + 20 zero bytes
except Exception as e:
print(f"Address decode error: {e}")
return bytes([0x00, 0x14]) + b'\x00' * 20
# Emergency fallback - this should never happen in production
return bytes([0x00, 0x14]) + bytes(20)
def build_coinbase_transaction(self, template, extranonce1, extranonce2):
"""Build complete coinbase transaction"""
@@ -101,8 +111,12 @@ class RinCoinStratumProxy:
# Version
coinbase += struct.pack('<I', 1)
# Segwit marker and flag (for witness commitment)
coinbase += b'\x00\x01'
# Check if we need segwit format based on template
has_witness_commitment = template.get('default_witness_commitment') is not None
if has_witness_commitment:
# Segwit marker and flag (only if witness commitment present)
coinbase += b'\x00\x01'
# Input count
coinbase += b'\x01'
@@ -122,7 +136,7 @@ class RinCoinStratumProxy:
# Sequence
coinbase += b'\xff\xff\xff\xff'
# Output count (main output + witness commitment if present)
# Prepare outputs
outputs = []
# Main output to mining address
@@ -136,14 +150,16 @@ class RinCoinStratumProxy:
commit_script = bytes.fromhex(witness_commitment)
outputs.append(struct.pack('<Q', 0) + self.encode_varint(len(commit_script)) + commit_script)
# Add outputs
coinbase += self.encode_varint(len(outputs))
for output in outputs:
coinbase += output
# Witness (for segwit)
coinbase += b'\x01' # witness stack count for input
coinbase += b'\x20' # witness item length (32 bytes)
coinbase += b'\x00' * 32 # witness nonce
# Witness data (only if segwit format)
if has_witness_commitment:
coinbase += b'\x01' # witness stack count for input
coinbase += b'\x20' # witness item length (32 bytes)
coinbase += b'\x00' * 32 # witness nonce
# Locktime
coinbase += struct.pack('<I', 0)
@@ -277,14 +293,20 @@ class RinCoinStratumProxy:
# Submit block
block_hex = block.hex()
print(f"Submitting block of size {len(block_hex)//2} bytes...")
result = self.rpc_call("submitblock", [block_hex])
if result is None:
print(f"Block accepted: {block_hash_hex}")
print(f"Reward: {job['coinbasevalue']/100000000:.2f} RIN -> {self.target_address}")
print(f"Block accepted: {block_hash_hex}")
print(f"💰 Reward: {job['coinbasevalue']/100000000:.2f} RIN -> {self.target_address}")
print(f"📊 Block height: {job['height']}")
return True, "Block found and submitted"
else:
print(f"Block rejected: {result}")
print(f"Block rejected: {result}")
print(f"📦 Block hash: {block_hash_hex}")
print(f"📊 Block height: {job['height']}")
print(f"🔍 Debug: Block size {len(block_hex)//2} bytes, {len(job['transactions'])} transactions")
return False, f"Block rejected: {result}"
except Exception as e:
@@ -387,7 +409,23 @@ class RinCoinStratumProxy:
else:
self.send_stratum_response(client, msg_id, False, message)
else:
self.send_stratum_response(client, msg_id, False, "Stale job")
# For stale jobs, still validate for blocks but don't require exact job match
# This prevents missing blocks due to job timing issues
if self.current_job:
extranonce1 = self.clients[addr].get('extranonce1', '00000000')
# Use current job template but allow stale job_id
success, message = self.submit_share(self.current_job, extranonce1, extranonce2, ntime, nonce)
if success:
self.send_stratum_response(client, msg_id, True)
if "Block found" in message:
# Get new job after block found
threading.Thread(target=self.update_job_after_block, daemon=True).start()
else:
# Accept as share even if block validation fails for stale jobs
self.send_stratum_response(client, msg_id, True)
else:
self.send_stratum_response(client, msg_id, True)
else:
self.send_stratum_response(client, msg_id, False, "Invalid parameters")