It was the Bitcointalk forum that inspired us to create Bitcointalksearch.org - Bitcointalk is an excellent site that should be the default page for anybody dealing in cryptocurrency, since it is a virtual gold-mine of data. However, our experience and user feedback led us create our site; Bitcointalk's search is slow, and difficult to get the results you need, because you need to log in first to find anything useful - furthermore, there are rate limiters for their search functionality.
The aim of our project is to create a faster website that yields more results and faster without having to create an account and eliminate the need to log in - your personal data, therefore, will never be in jeopardy since we are not asking for any of your data and you don't need to provide them to use our site with all of its capabilities.
We created this website with the sole purpose of users being able to search quickly and efficiently in the field of cryptocurrency so they will have access to the latest and most accurate information and thereby assisting the crypto-community at large.
def assign_random_range(puzzle_id, client_increment):
"""
Assigns a random range to the client, ensuring uniformly random selection
across the puzzle space for all "big-enough" ranges.
Steps:
1. Fetch all available ranges from the database.
2. Classify ranges into "big-enough" and "smaller."
3. If "big-enough" ranges exist:
- Perform weighted random selection based on range size.
- Assign a subrange of length `client_increment` and update the database.
4. Otherwise, assign the largest "smaller" range.
5. Return `None` if no suitable ranges are available.
Args:
puzzle_id (int): The ID of the puzzle to fetch ranges for.
client_increment (int): The size of the range to assign.
Returns:
tuple or None: Assigned range as (start, end) or None if no range is available.
"""
conn = None
def fetch_ranges(cursor, puzzle_id):
"""Retrieve and convert all available ranges for the given puzzle ID."""
cursor.execute('''
SELECT start_range, end_range
FROM available_work_ranges
WHERE puzzle_id = ?
''', (puzzle_id,))
return [
(int(start_hex, 16), int(end_hex, 16))
for (start_hex, end_hex) in cursor.fetchall()
]
def update_database(cursor, puzzle_id, chosen_start, chosen_end, assigned_start, assigned_end):
"""Remove the chosen range and reinsert remaining parts into the database."""
# Remove the old range
cursor.execute('''
DELETE FROM available_work_ranges
WHERE puzzle_id = ? AND start_range = ? AND end_range = ?
''', (puzzle_id, hex(chosen_start)[2:], hex(chosen_end)[2:]))
# Reinsert leftover front
if assigned_start > chosen_start:
cursor.execute('''
INSERT INTO available_work_ranges (puzzle_id, start_range, end_range)
VALUES (?, ?, ?)
''', (puzzle_id, hex(chosen_start)[2:], hex(assigned_start - 1)[2:]))
# Reinsert leftover back
if assigned_end < chosen_end:
cursor.execute('''
INSERT INTO available_work_ranges (puzzle_id, start_range, end_range)
VALUES (?, ?, ?)
''', (puzzle_id, hex(assigned_end + 1)[2:], hex(chosen_end)[2:]))
def weighted_random_pick(big_enough, client_increment):
"""Select a range weighted by size and assign a subrange."""
total_space = sum(rsize for (_, _, rsize) in big_enough)
pivot = random.randint(0, total_space - 1)
cumulative = 0
for (rstart, rend, rsize) in big_enough:
if pivot < cumulative + rsize:
max_start = rend - client_increment + 1
assigned_start = random.randint(rstart, max_start)
assigned_end = assigned_start + client_increment - 1
return rstart, rend, assigned_start, assigned_end
cumulative += rsize
try:
conn = get_db_connection()
cursor = conn.cursor()
# Step 1: Fetch all ranges
all_ranges = fetch_ranges(cursor, puzzle_id)
if not all_ranges:
logging.error(f"No available ranges for puzzle_id {puzzle_id}.")
return None
# Step 2: Classify ranges
big_enough, smaller = [], []
for rstart, rend in all_ranges:
size = rend - rstart + 1
(big_enough if size >= client_increment else smaller).append((rstart, rend, size))
# Step 3: Handle "big-enough" ranges
if big_enough:
chosen_start, chosen_end, assigned_start, assigned_end = weighted_random_pick(big_enough, client_increment)
update_database(cursor, puzzle_id, chosen_start, chosen_end, assigned_start, assigned_end)
conn.commit()
return assigned_start, assigned_end
# Step 4: Handle "smaller" ranges
if smaller:
smaller.sort(key=lambda x: x[1] - x[0], reverse=True)
sstart, send = smaller[0][:2]
cursor.execute('''
DELETE FROM available_work_ranges
WHERE puzzle_id = ? AND start_range = ? AND end_range = ?
''', (puzzle_id, hex(sstart)[2:], hex(send)[2:]))
conn.commit()
return sstart, send
# Step 5: No suitable ranges
logging.debug(f"No suitable range found for puzzle_id {puzzle_id}.")
return None
except Exception as e:
logging.error(f"Error assigning random range for puzzle_id {puzzle_id}: {e}")
if conn:
conn.rollback()
return None
finally:
if conn:
conn.close()
GPU : GPU #0 NVIDIA GeForce RTX 3080 (68x128 cores) Grid(544x128)
[00:00:58] [GPU: 2101.64 Mk/s] [C: 102.44 %] [T: 122,926,661,632 (37 bit)] [Puzzle: 67] [Shares: 465.00 ] [EST Payment: 0.053736 BTC] [Searched: 0.000713 %]
Start Time : Thu Dec 26 10:53:31 2024
Global range : 0000000000000000000000000000000000000000000000000000001BF08EAFFF (37 bit)
GPU : GPU #0 NVIDIA GeForce RTX 3080 (68x128 cores) Grid(544x128)
[00:00:58] [GPU: 2113.36 Mk/s] [C: 102.68 %] [T: 123,211,874,304 (37 bit)] [Puzzle: 67] [Shares: 477.00 ] [EST Payment: 0.055123 BTC] [Searched: 0.000713 %]
Start Time : Thu Dec 26 10:54:31 2024
Global range : 0000000000000000000000000000000000000000000000000000001BF08EAFFF (37 bit)
2024-12-26 11:21:44,470 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 completed work range 791b4951faef50cb3-791b4953b9f83bcb2 in 60.97 seconds - 1968.08 Mk/s
2024-12-26 11:21:44,535 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 assigned work range 5f2f790baa55217bf-5f2f790d695e0c7be
2024-12-26 11:21:50,378 - INFO - Puzzle ID 67: 0.00071820 % of the range has been searched.
2024-12-26 11:22:18,809 - INFO - Updated balance for puzzle_id 67: 6.70010696 BTC
2024-12-26 11:22:45,455 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 completed work range 5f2f790baa55217bf-5f2f790d695e0c7be in 60.91 seconds - 1970.09 Mk/s
2024-12-26 11:22:45,529 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 assigned work range 578f6ad3304fbeab4-578f6ad4ef58a9ab3
2024-12-26 11:22:50,403 - INFO - Puzzle ID 67: 0.00071837 % of the range has been searched.
2024-12-26 11:23:19,363 - INFO - Updated balance for puzzle_id 67: 6.70010696 BTC
2024-12-26 11:23:46,582 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 completed work range 578f6ad3304fbeab4-578f6ad4ef58a9ab3 in 61.05 seconds - 1965.74 Mk/s
2024-12-26 11:23:46,660 - INFO - Client 37CDsFQ4wN5xjAnuSe5CxvPbk7H2vhH2kv:3080-2 assigned work range 4563b3389517d413c-4563b33a5420bf13b
2024-12-26 11:23:50,429 - INFO - Puzzle ID 67: 0.00071853 % of the range has been searched.