Skip to content

Commit

Permalink
Merge branch 'main' of github.com:shanhaicoder/XENGPUMiner
Browse files Browse the repository at this point in the history
# Conflicts:
#	miner.py
  • Loading branch information
shanhaicoder committed Oct 12, 2023
2 parents a3285ea + 25f6f72 commit dd19f49
Show file tree
Hide file tree
Showing 11 changed files with 1,026 additions and 10 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ blockchain.db-journal
hash_rates/
.idea
logs/
dist/
miner.spec
130 changes: 130 additions & 0 deletions dev/ptrie_db_tests.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
import sqlite3
from trie import HexaryTrie

class SQLiteDB:
def __init__(self, db_path):
self.conn = sqlite3.connect(db_path)
self.cursor = self.conn.cursor()
self.setup()

def setup(self):
self.cursor.execute("CREATE TABLE IF NOT EXISTS trie_data (key TEXT UNIQUE, value TEXT)")
self.cursor.execute("CREATE TABLE IF NOT EXISTS block_meta (block_id INTEGER PRIMARY KEY, root_hash TEXT)")
self.conn.commit()

def __getitem__(self, key):
self.cursor.execute("SELECT value FROM trie_data WHERE key=?", (key.hex(),))
value = self.cursor.fetchone()
if value:
return bytes.fromhex(value[0])
else:
raise KeyError(key)

def __setitem__(self, key, value):
hex_key = key.hex()
hex_value = value.hex()
self.cursor.execute("INSERT OR IGNORE INTO trie_data (key, value) VALUES (?, ?)", (hex_key, hex_value))
self.conn.commit()

def set_root_hash(self, block_id, root_hash):
self.cursor.execute("REPLACE INTO block_meta (block_id, root_hash) VALUES (?, ?)", (block_id, root_hash.hex()))
self.conn.commit()

def get_root_hash(self, block_id):
self.cursor.execute("SELECT root_hash FROM block_meta WHERE block_id=?", (block_id,))
root_hash = self.cursor.fetchone()
return bytes.fromhex(root_hash[0]) if root_hash else None

def close(self):
self.conn.close()

class AccountManager:
def __init__(self, db_path):
self.db = SQLiteDB(db_path)
self.trie = HexaryTrie(self.db)

def set_balances(self, balances, block_id):
for account, balance in balances.items():
key = account.encode()
value = str(balance).encode()
self.trie[key] = value
self.db.set_root_hash(block_id, self.trie.root_hash)

def get_balance(self, account):
key = account.encode()
return int(self.trie.get(key) or b'0')

def credit_balances(self, credits, block_id):
new_balances = {}
for account, amount in credits.items():
balance = self.get_balance(account)
new_balances[account] = balance + amount
self.set_balances(new_balances, block_id)

def debit_balances(self, debits, block_id):
new_balances = {}
for account, amount in debits.items():
balance = self.get_balance(account)
if balance < amount:
raise ValueError(f"Insufficient balance for account {account}")
new_balances[account] = balance - amount
self.set_balances(new_balances, block_id)


def rebuild_trie(self, block_id):
root_hash = self.db.get_root_hash(block_id)
self.trie = HexaryTrie(self.db, root_hash)


import time
if __name__ == "__main__":
manager = AccountManager('ptrie.db')

# Operations with block_id 1
manager.set_balances({
'0xSomeAccount1': 100,
'0xSomeAccount2': 200
}, 1)

# Start measuring time for credit_balances loop
start_time_credit_balances = time.time()

# Create 100 transactions
for i in range(2, 100000):
manager.credit_balances({
'0xSomeAccount1': 1,
'0xSomeAccount2': 1
}, i)

# Print progress every 10,000 iterations
if i % 10000 == 0:
print(f"credit_balances progress: {i}/1000000")

# Calculate and print the rate for credit_balances loop
end_time_credit_balances = time.time()
duration_credit_balances = end_time_credit_balances - start_time_credit_balances
rate_credit_balances = 1000000 / duration_credit_balances
print(f"credit_balances runs per second: {rate_credit_balances:.2f}")

# Start measuring time for rebuild_trie loop
start_time_rebuild_trie = time.time()

# Loop to rebuild the trie for block_ids from 50 to 101 and print the balance for each
for i in range(50, 100000):
manager.rebuild_trie(i)

# Print progress every 10,000 iterations
if (i - 50) % 10000 == 0:
print(f"rebuild_trie progress: {i}/1000000")

print(f"Balance for block_id {i} (Account1):", manager.get_balance('0xSomeAccount1'))
print(f"Balance for block_id {i} (Account2):", manager.get_balance('0xSomeAccount2'))

# Calculate and print the rate for rebuild_trie loop
end_time_rebuild_trie = time.time()
duration_rebuild_trie = end_time_rebuild_trie - start_time_rebuild_trie
rate_rebuild_trie = (1000000 - 50) / duration_rebuild_trie
print(f"rebuild_trie runs per second: {rate_rebuild_trie:.2f}")

# Close the db connection
manager.db.close()
Binary file added docs/XENIUM_BLOCKCHAIN.pdf
Binary file not shown.
3 changes: 3 additions & 0 deletions go/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module example.com/xenminer

go 1.18
56 changes: 56 additions & 0 deletions go/merkle_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package main

import (
"crypto/sha256"
"encoding/hex"
"fmt"
"testing"
)

func hashValue(value string) string {
hash := sha256.Sum256([]byte(value))
return hex.EncodeToString(hash[:])
}

func buildMerkleTree(elements []string, merkleTree map[string][2]string) string {
if len(elements) == 1 {
return elements[0]
}

var newElements []string
for i := 0; i < len(elements); i += 2 {
left := elements[i]
var right string
if i+1 < len(elements) {
right = elements[i+1]
} else {
right = left
}
combined := left + right
newHash := hashValue(combined)
merkleTree[newHash] = [2]string{left, right}
newElements = append(newElements, newHash)
}
return buildMerkleTree(newElements, merkleTree)
}

func TestHashValue(t *testing.T) {
expected := sha256.Sum256([]byte("hello"))
if hashValue("hello") != hex.EncodeToString(expected[:]) {
t.Errorf("hashValue function not working properly")
}
}

func TestBuildMerkleTree(t *testing.T) {
elements := []string{"a", "b", "c", "d"}
merkleTree := make(map[string][2]string)
root := buildMerkleTree(elements, merkleTree)
fmt.Printf("Merkle Root: %s\n", root)

expectedRoot := hashValue(hashValue("a"+"b") + hashValue("c"+"d"))
if root != expectedRoot {
t.Errorf("buildMerkleTree function not working properly")
}
// Add more tests to validate the structure of merkleTree if necessary.
}

103 changes: 100 additions & 3 deletions gpage.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ def leaderboard():
cache_c = cache_conn.cursor()

# Read from the cache table for leaderboard data
cache_c.execute("SELECT * FROM cache_table ORDER BY total_blocks DESC LIMIT 500")
cache_c.execute("SELECT * FROM cache_table ORDER BY total_blocks DESC")
results = cache_c.fetchall()
cache_conn.close()

Expand Down Expand Up @@ -228,6 +228,44 @@ def leaderboard():
latest_rate=latest_rate, latest_miners=latest_miners, difficulty=difficulty)


@app.route('/get_balance/<account>', methods=['GET'])
def get_balance(account):
conn = None
try:
conn = sqlite3.connect('cache.db', timeout=10)
cursor = conn.cursor()
cursor.execute("SELECT total_blocks FROM cache_table WHERE LOWER(account) = LOWER(?)", (account,))
row = cursor.fetchone()
if row:
balance = row[0] * 10
return jsonify({'account': account, 'balance': balance})
else:
return jsonify({'error': 'No record found for the provided account'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500
finally:
if conn:
conn.close()

@app.route('/get_super_blocks/<account>', methods=['GET'])
def get_super_blocks(account):
conn = None
try:
conn = sqlite3.connect('cache.db', timeout=10)
cursor = conn.cursor()
cursor.execute("SELECT super_blocks FROM cache_table WHERE LOWER(account) = LOWER(?)", (account,))
row = cursor.fetchone()
if row:
return jsonify({'account': account, 'super_blocks': row[0]})
else:
return jsonify({'error': 'No record found for the provided account'}), 404
except Exception as e:
return jsonify({'error': str(e)}), 500
finally:
if conn:
conn.close()


@app.route('/total_blocks', methods=['GET'])
def total_blocks():
conn = sqlite3.connect('blocks.db')
Expand Down Expand Up @@ -282,10 +320,47 @@ def check_fourth_element(string):
match = pattern.search(string)
return bool(match)

def is_valid_hash(h):
"""Ensure the input is a hexadecimal hash of the expected length."""
return bool(re.match("^[a-fA-F0-9]{64}$", h))


@app.route('/get_block', methods=['GET'])
def get_block():
key = request.args.get('key')
if not key:
return jsonify({"error": "Please provide a key"}), 400

if not is_valid_hash(key):
return jsonify({"error": "Invalid key provided"}), 400

conn = sqlite3.connect('blocks.db')
cursor = conn.cursor()

# Use a parameterized query to prevent SQL injection
cursor.execute("SELECT * FROM blocks WHERE key=?", (key,))
data = cursor.fetchone()

if data is None:
return jsonify({"error": "Data not found for provided key"}), 404

# Convert the tuple data to a dictionary
columns = ['block_id', 'hash_to_verify', 'key', 'account', 'created_at']
data_dict = dict(zip(columns, data))

conn.close()

return jsonify(data_dict), 200

@app.route('/verify', methods=['POST'])
def verify_hash():
global account_attempts_batch, blocks_batch
data = request.json
worker_id = data.get('worker_id')

if not (isinstance(worker_id, str) and len(worker_id) <= 3):
worker_id = None # Set worker_id to None if it's not a valid string of 3 characters or less

hash_to_verify = data.get('hash_to_verify')
hash_to_verify = hash_to_verify if (hash_to_verify and len(hash_to_verify) <= 140) else None
is_xuni_present = re.search('XUNI[0-9]', hash_to_verify[-87:]) is not None
Expand Down Expand Up @@ -351,7 +426,7 @@ def verify_hash():
print (error_message, hash_to_verify[-87:])
return jsonify({"message": error_message}), 401

if len(hash_to_verify) > 137:
if len(hash_to_verify) > 139:
error_message = "Length of hash_to_verify should not be greater than 137 characters."
print (error_message)
log_verification_failure(error_message, account)
Expand Down Expand Up @@ -392,7 +467,7 @@ def verify_hash():
except sqlite3.IntegrityError as e:
error_message = e.args[0] if e.args else "Unknown IntegrityError"
print(f"Error: {error_message} ", hash_to_verify, key, account)
return jsonify({"message": f"Error detected: {error_message}"}), 400
return jsonify({"message": f"Block already exists, continue"}), 400

finally:
conn.close()
Expand Down Expand Up @@ -425,6 +500,28 @@ def store_consensus():
return jsonify({"status": "error", "message": str(e)})


@app.route('/top_daily_block_miners', methods=['GET'])
def get_top_blocks():
conn = sqlite3.connect('blocks.db') # Assuming your database file is named blocks.db
cursor = conn.cursor()

query = '''
SELECT * FROM AccountBlockCounts
ORDER BY num_blocks DESC
LIMIT 500
'''

cursor.execute(query)
rows = cursor.fetchall()

# Close the connection
conn.close()

# Convert the rows to a JSON response
result = [{"account": row[0], "num_blocks": row[1]} for row in rows]
return jsonify(result)


@app.route('/latest_blockrate', methods=['GET'])
def get_latest_blockrate():
try:
Expand Down
9 changes: 4 additions & 5 deletions miner.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ def update_memory_cost_periodically():
def fetch_difficulty_from_server():
global memory_cost
try:
response = requests.get('http://xenminer.mooo.com/difficulty', timeout=10)
response = requests.get('http://xenblocks.io/difficulty', timeout=10)
response_data = response.json()
return str(response_data['difficulty'])
except Exception as e:
Expand Down Expand Up @@ -254,8 +254,7 @@ def submit_pow(account_address, key, hash_to_verify):

# Send POST request
try:
pow_response = requests.post('http://xenminer.mooo.com:4446/send_pow', json=payload)

pow_response = requests.post('http://xenblocks.io:4446/send_pow', json=payload)
if pow_response.status_code == 200:
print(f"Proof of Work successful: {pow_response.json()}")
else:
Expand Down Expand Up @@ -348,7 +347,7 @@ def mine_block(stored_targets, prev_hash):
while retries <= max_retries:
try:
# Make the POST request
response = requests.post('http://xenminer.mooo.com/verify', json=payload)
response = requests.post('http://xenblocks.io/verify', json=payload, timeout=10)

# Print the HTTP status code
print("HTTP Status Code:", response.status_code)
Expand Down Expand Up @@ -441,7 +440,7 @@ def submit_block(key):
while retries <= max_retries:
try:
# Make the POST request
response = requests.post('http://xenminer.mooo.com/verify', json=payload)
response = requests.post('http://xenblocks.io/verify', json=payload, timeout=10)

# Print the HTTP status code
print("HTTP Status Code:", response.status_code)
Expand Down
Loading

0 comments on commit dd19f49

Please sign in to comment.