Author

Topic: Public Bitcoin Challenge Pool (Read 424 times)

?
Activity: -
Merit: -
Today at 07:55:36 AM
#16
I have put together a basic webpage to view the current pool stats as well as lookup your workers via the bitcoin address

https://www.challengepool.net/



Thanks I followed your Project on Github, I should be able to try the client out later today.
member
Activity: 135
Merit: 14
December 31, 2024, 10:43:54 PM
#15
I have put together a basic webpage to view the current pool stats as well as lookup your workers via the bitcoin address

https://www.challengepool.net/

member
Activity: 135
Merit: 14
December 29, 2024, 09:57:15 PM
#14
I am quite happy to share portions of the server code for external validation / improvements.  The problems of the clients (all clients must be considered to be untrusted) I don't really have a bullet proof solution to the problems and am happy to explore options that other people might think of to make it less practical for a client to skim the private key from the pool.  I am happy to add notifications to the workers if a solution is submitted, this is not a difficult thing to adjust in the programs.   The pool checks the balance of the target puzzle address every couple of minutes to confirm that the prize is still in the account.  It has not been implemented yet that if the balance goes to 0 that we shift to the next puzzle.  We would do that if a valid solution was submitted to the pool.

I have considered a number of different options of masking / encryption of the search block, however in the end the clients must run the address check with the actual private key hex or they will never return any correct solutions.  In order for that to happen they need to be sent the information that is required to decrypt / unmask the value and are left with the raw hex anyway.  If anyone has any techniques that they think would be assistance to this problem it would be worth exploring.

There are a number of things that I would be more then happy to adjust / improve if there is sufficient interest in pursuing the pool.  The share system right now is setup as a proportional share system, each client that completes 1 work increment (WORK_INCREMENT = 10,000,000,000 private keys) gets 1 share.  The current calculation allocates shares to each puzzle independently so if puzzle 67 is solved, shares are logged for 67 and a new count starts for 68.  I do see the merit in carrying over shares if the solution is found by a different party as it would still reward any workers for past work and only reset if the pool finds a solution.


The logic for the 60 second work increment is so that it is easer to track progress / update searched ranges / return non responsive work back to the pool.

The work is being distributed in a weighted random selection search method.  The basis is that it will try and break up larger unsearched areas into smaller and smaller ranges.  Once the ranges get to be smaller then the requested search size the pool will start returning the smaller ranges to close gaps between completed work.  This process seemed to work well in testing with the easier puzzles.

This is the function that does the work assignments, yes I am just using SQLite for the time being as I am the only client, this will be migrated to a different database if/when the need arise.

Code:
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()


In regards to the solo vs pool, I cannot understand the logic of a solo pool that uses work from other workers?  Its like saying I want to use the pool work but I get the full reward if I am the lucky one to find the key.  A larger reward for the lucky person would make more sense if that was what people are looking for.

 
full member
Activity: 1232
Merit: 242
Shooters Shoot...
December 29, 2024, 12:48:06 AM
#13
There are at least 3 public pools that I know of that have already completed a decent amount of ranges, for the 67 challenge / puzzle. I think one is near 4.5-5% (1.4 - 2 million, 41 bit ranges) complete.
Each has their own website and an abundance of information.

My layman opinion is that the pools should coordinate each other to at least share the ranges that have already been explored and are empty, so that nobody is waiting for years trying to find those keys while they brute-force the same ranges.

Then again, that doesn't seem to be a problem, at least not for whoever found #64, #66, and all of those puzzles with public keys.
One is a solo pool, but once a range is completed by one person, it marks it off for everybody.

The other 2 that are shared, use encryption for the ranges. I think the one may know which ranges have been searched, but the other one 100% does not. That was implemented to prevent anyone from spoofing and gathering ranges that haven't been ran yet (including those who have server side access, like admin).
I'm not sure why anyone still runs the one pool, as it has duped members before, and will dupe them again lol. I just hope the other shared pool, finds the key this time.

It would be best to just have one pool, that has shared and solo setups. I thought about creating one, but other things came up. If you have ever mined, say on 2miners, you have the option of solo or shared. Same concept with this pool, but all ranges completed are marked as searched, regardless if you are hashing for shared or solo. Basically use a -solo flag, or a different port, or something like that.
legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
December 29, 2024, 12:04:18 AM
#12
There are at least 3 public pools that I know of that have already completed a decent amount of ranges, for the 67 challenge / puzzle. I think one is near 4.5-5% (1.4 - 2 million, 41 bit ranges) complete.
Each has their own website and an abundance of information.

My layman opinion is that the pools should coordinate each other to at least share the ranges that have already been explored and are empty, so that nobody is waiting for years trying to find those keys while they brute-force the same ranges.

Then again, that doesn't seem to be a problem, at least not for whoever found #64, #66, and all of those puzzles with public keys.
full member
Activity: 1232
Merit: 242
Shooters Shoot...
December 28, 2024, 11:22:16 PM
#11
There are at least 3 public pools that I know of that have already completed a decent amount of ranges, for the 67 challenge / puzzle. I think one is near 4.5-5% (1.4 - 2 million, 41 bit ranges) complete.
Each has their own website and an abundance of information.

Why are you adjusting / limiting the time for range completion, at 60 seconds?
legendary
Activity: 3472
Merit: 10611
December 28, 2024, 10:24:40 PM
#10
I'm pretty new to this forum. Are there still unsolved bitcoin challenge puzzles? Where can I read more about them?
This is about one of the oldest "puzzles" on bitcointalk that takes an increasing amount of computing power to solve the subsequent cases or better said to brute force them. You can find the original topic and related discussions here: https://bitcointalksearch.org/topic/bitcoin-puzzle-transaction-32-btc-prize-to-who-solves-it-1306983
?
Activity: -
Merit: -
December 28, 2024, 10:16:10 PM
#9
I'm pretty new to this forum. Are there still unsolved bitcoin challenge puzzles? Where can I read more about them?
hero member
Activity: 714
Merit: 1010
Crypto Swap Exchange
December 28, 2024, 08:32:25 AM
#8
How and why should someone trust you to install and run black-box software and believe that your server component does its magic correct, fair and reliable? Your account woke up after little less than six years of no posting in the forum. Hmm...

My first impulse was: your justification to remain closed-source is bullshit, but after thinking a bit about it, I see the problem that you need to hide and obscure how client and server communicate work and work done to avoid malicious fake work which would also spoil your database of successfully scanned regions.

For obvious reasons it doesn't make much sense for a malicious client to fake work done on submitted regions to be scanned but who says that malicious actors always play by good reasoning. Let's assume a malicious actor has reverse-engineered your client and sabotages your project by responding with fake work done for his scan regions. This would spoil your database of unsuccessful regions done which may lead to never finding a solution for a puzzle.
Or worse, the altered client could be lucky to find a solution and claim the withdrawal via slipstream.mara.com for its own, while reporting back to your server an unsuccessful scan of the region, faking no solution found to your server. This would give the malicious actor time until slipstream.mara.com confirms this own transaction.

How do you ensure that your unsuccessful (scanned but no solution found) regions database is protected by any means from corruption, loss or anything that would spoil a thorough exhaustive search of a puzzle's private key range? The avoidance of curruption or loss is crucial for such a distributed work scenario!

Bad for transparency is also that nobody can check if your server component can construct the withdrawal transaction for slipstream.mara.com in a fair and correct way.

Here I suggest that your server at least publishes a "solution found" notification to all clients with a SHA-256 or SHA-384 or SHA-512 hash of the transaction immediately when submitted to slipstream.mara.com, including a timestamp of submission. This way you document and show proof that and what your server has submitted to slipstream.mara.com. Not only it isn't guaranteed that slipstream.mara.com will completely automatically process your transaction but also it will take time for Mara pool to find an own block which should include the non-public transaction. Everybody has to trust slipstream.mara.com to act trustworthy and not benefit somehow on their own to steal a puzzle. You can't reliably check if a concurrent puzzle withdrawal was maliciously done by slipstream.mara.com or someone else who got lucky to find a puzzle's solution.
member
Activity: 135
Merit: 14
December 28, 2024, 12:04:12 AM
#7
I have released the first set of compiled clients if anyone is interested in trying and contributing to the testing.

https://github.com/jrharp/challengepool.net/releases/tag/v1.0

There is a link to the discord there if anyone has issues, thoughts or suggestions.

member
Activity: 135
Merit: 14
December 26, 2024, 12:43:41 AM
#6
If you are unaware of the Bitcoin Challenge Puzzles, there is a lot of information about it in this thread.

https://bitcointalksearch.org/topic/bitcoin-puzzle-transaction-32-btc-prize-to-who-solves-it-1306983

and some basic details here

https://privatekeys.pw/puzzles/bitcoin-puzzle-tx

Why are you calling it a "mining" pool? It is a pool but there is no mining, it is just solving a "puzzle" which is not "the Bitcoin Challenge" as you put it. This is just a puzzle or rather a brute forcing game. Smiley



I changed the name so it is more appropriate to the task

Yes it is just the brute forcing game, and if we all sit and individually brute force the full range in the next 6,000 or so years one of us might get lucky and find it alone.


legendary
Activity: 1568
Merit: 6660
bitcoincleanup.com / bitmixlist.org
December 26, 2024, 12:32:57 AM
#5
Why are you calling it a "mining" pool? It is a pool but there is no mining, it is just solving a "puzzle" which is not "the Bitcoin Challenge" as you put it. This is just a puzzle or rather a brute forcing game. Smiley

It is technically a "de-mining" pool. You are trying to find lost bitcoins that have already been mined, transfer them out as quickly as possible, and construct your signing transaction properly so that some bots can't just fee-snipe your transaction and make it all go to miners as a transaction fee. Smiley

Although I think, this particular pool only supports address mode.
legendary
Activity: 3472
Merit: 10611
December 25, 2024, 11:51:37 PM
#4
Why are you calling it a "mining" pool? It is a pool but there is no mining, it is just solving a "puzzle" which is not "the Bitcoin Challenge" as you put it. This is just a puzzle or rather a brute forcing game. Smiley

Also Project Development board is a more appropriate place to post these things (there is a move topic button at the bottom of the page).
newbie
Activity: 6
Merit: 0
December 25, 2024, 09:38:59 PM
#3
Nice Work.
Willing to include
member
Activity: 135
Merit: 14
December 25, 2024, 09:21:21 PM
#2
** Reserved **
member
Activity: 135
Merit: 14
December 25, 2024, 09:21:04 PM
#1
Hello Everyone,

I’ve been working on a public mining pool designed to help a community collaborate on solving some of the Bitcoin challenge puzzles. The goal is to make the pool as transparent as possible while taking steps to secure the private key from misuse if a miner finds the solution.  Please keep in mind that due to this the client and server software will have to remain closed source as there is no way to get around the clients having to work with the physical private key hex values.

I’ve built a working client/server package that distributes work to clients in a randomized manner from the current puzzle range. The server dynamically adjusts the assigned work so that each client completes its range in approximately 60 seconds, sends back the result, and receives its next random block of work. This ensures consistent and efficient participation across the pool.

While the system is functional, I’d love to hear the community’s thoughts and suggestions on improving the security and functionality of the pool. This includes ways to enhance transparency, protect the private key, and build trust in the process.

At the moment, I have not put together a web interface as I have been focusing on the core client and server software. However, the client software provides updates on the miner's stats, the estimated BTC payout if the solution were found now, and the total search range that the pool has completed.

The client is a modified version of the KeyHunt software, as it was in a format that allowed for relatively easy modification to include the pool functions.

The server code is written in Python, with persistent storage for the work ranges that have been completed, as well as client work and related data.

If the pool does find the solution, the transaction will be generated to distribute the funds among the miners based on their share percentage and submitted via slipstream.mara.com. This is designed to reduce the risk of the transaction being broadcast to the full Bitcoin network mempool, as this could potentially result in the transaction being hijacked.

I am looking for anyone who would be interested in providing feedback or willing to point any GPUs at the server to help continue working through bugs.

Looking forward to your feedback!

Client Output:
Code:
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)

Server Output:
Code:
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.
Jump to: