Author

Topic: Can a getwork be returned to different bitcoind than the one you got it from? (Read 1581 times)

sr. member
Activity: 266
Merit: 254
Quote
Yes.  The server sends the data block to the client with the nonce field set to 0.  The client iterates through the 2^32 possible nonces, checking each one.  If it finds one that meets the target, it sends the modified block back.

Thanks kkj.  That's exactly what I needed to know and exactly the part that is pretty fuzzy on the API calls and getwork wiki pages.  It does explain it in part but it doesn't really say clearly that 'data'=block_header.  Can anyone create an account on the wiki and edit?  If so I might try to tidy that up a bit because I'm sure I'm not the first or last person it's going leave scratching their head.
kjj
legendary
Activity: 1302
Merit: 1026
I look forward to finding out what you hope to accomplish with this.

Shoudn't be more than a few days after I figure this bit out...

Quote
The data field will be unique, at the very least to the server and block in progress.  You can record that with the server it came from.  Or, since you are changing both the proxy and the client, you could just have the proxy add a field that just says what server to give the work back to, and have the client return that when it returns the candidate hashes.

So the 'data' field that the miner returns is somehow related to the 'data' field in the getwork response.  But it couldn't be the same or the server already has the block solved. 

Is the data field just the block header with the nonce altered to produce a valid block?

Yes.  The server sends the data block to the client with the nonce field set to 0.  The client iterates through the 2^32 possible nonces, checking each one.  If it finds one that meets the target, it sends the modified block back.

There are circumstances where the server can send the exact same block out more than once, but this is rare, and you can't do anything about it until the node software is fixed.  But, each node will have a totally different coinbase transaction included in the Merkle tree, so you will never get the same data block from two different servers, allowing you to always identify which server gave which work.
sr. member
Activity: 266
Merit: 254
I look forward to finding out what you hope to accomplish with this.

Shoudn't be more than a few days after I figure this bit out...

Quote
The data field will be unique, at the very least to the server and block in progress.  You can record that with the server it came from.  Or, since you are changing both the proxy and the client, you could just have the proxy add a field that just says what server to give the work back to, and have the client return that when it returns the candidate hashes.

So the 'data' field that the miner returns is somehow related to the 'data' field in the getwork response.  But it couldn't be the same or the server already has the block solved.  

Is the data field just the block header with the nonce altered to produce a valid block?
kjj
legendary
Activity: 1302
Merit: 1026
For most clients you're correct that the assumption is wrong but I'm talking about a client that operates a little differently which is part of the same project I'm building.

I look forward to finding out what you hope to accomplish with this.

The data field will be unique, at the very least to the server and block in progress.  You can record that with the server it came from.  Or, since you are changing both the proxy and the client, you could just have the proxy add a field that just says what server to give the work back to, and have the client return that when it returns the candidate hashes.
sr. member
Activity: 266
Merit: 254
I have a perfectly good reason which will be obvious when the project is ready for release.  You said 'first of all' so I guess next you were going to suggest an answer to the question?
legendary
Activity: 1260
Merit: 1000
First of all, why would you do that?  If you work on multiple getworks at the same time, you slow your completion rate down and increase your chance of a stale share.

I can't see any reason why you'd do that *except* to queue work up for a slow link.  But again, you run into the problem of increasing your stale shares dramatically.
sr. member
Activity: 266
Merit: 254
For most clients you're correct that the assumption is wrong but I'm talking about a client that operates a little differently which is part of the same project I'm building.
kjj
legendary
Activity: 1302
Merit: 1026
True but I'm assuming the client can make multiple getwork requests (which could each be server from a different upstream server) and that there's no garuntee that client is submitting the most recently aquired work.

Your assumption is wrong.

Every client works on one getwork request at a time, and always the most recent.
sr. member
Activity: 266
Merit: 254
True but I'm assuming the client can make multiple getwork requests (which could each be served from a different upstream server) and that there's no garuntee that client is submitting the most recently aquired work.
kjj
legendary
Activity: 1302
Merit: 1026
So my next ask is to figure out how to match a submitted getwork to the server it came from.

i.e.
- client requests work
- proxy returns work from one of several servers
- proxy keeps mapping of work sent to upstream server
- Client submits completed work
- proxy verifies work and then looks up mapping to find correct server to submit to

The doco is a bit hazy on this.  I presume from here: https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list
that the data is the actual block.  Proxy verifies by double hashing it and comparing difficulty.  But how do I match it?  All the proxy has is the original getwork request with:

    "midstate" : precomputed hash state after hashing the first half of the data
    "data" : block data
    "hash1" : formatted hash buffer for second hash
    "target" : little endian hash target

Is the block data contained within the block submitted by the client?  According to this page: https://en.bitcoin.it/wiki/Protocol_specification#Block_Headers There's no data in the block header. 

The target is useless since they'll all have the same one.  No idea what the midstate and hash1 fields are.  So is there any what to identify it as the result of a particular work request or is it simply not built into the design to be able to match like this?

The proxy is not limited to the information in the blocks itself.  It is allowed to keep a record for itself of which server provided the most recent work request for each client.
sr. member
Activity: 266
Merit: 254
So my next ask is to figure out how to match a submitted getwork to the server it came from.

i.e.
- client requests work
- proxy returns work from one of several servers
- proxy keeps mapping of work sent to upstream server
- Client submits completed work
- proxy verifies work and then looks up mapping to find correct server to submit to

The doco is a bit hazy on this.  I presume from here: https://en.bitcoin.it/wiki/Original_Bitcoin_client/API_Calls_list
that the data is the actual block.  Proxy verifies by double hashing it and comparing difficulty.  But how do I match it?  All the proxy has is the original getwork request with:

    "midstate" : precomputed hash state after hashing the first half of the data
    "data" : block data
    "hash1" : formatted hash buffer for second hash
    "target" : little endian hash target

Is the block data contained within the block submitted by the client?  According to this page: https://en.bitcoin.it/wiki/Protocol_specification#Block_Headers There's no data in the block header. 

The target is useless since they'll all have the same one.  No idea what the midstate and hash1 fields are.  So is there any what to identify it as the result of a particular work request or is it simply not built into the design to be able to match like this?
legendary
Activity: 1072
Merit: 1181
The miner only sees the block header - the client remembers which block contents (=transactions) match with it. Since you need to know which transactions to add to it, you need the bitcoind that gave it to you. Furthermore, the header depends on all transactions in the block, so if you'd add the wrong ones, the header wouldn't be valid anymore.

Short answer: no
kjj
legendary
Activity: 1302
Merit: 1026
The miner only has the block header, which is not useful without the actual block that goes with it.  The completed work must be returned to the pool (node) that issued it.
sr. member
Activity: 266
Merit: 254
so even if the client passes it on as is?  What I mean is that I don't want the alternative client to try and claim the block, just that it should pass the block onto the network so the original issuer of the getwork request is credited with the new block.
legendary
Activity: 1596
Merit: 1012
Democracy is vulnerable to a 51% attack.
I believe that if you return it to a different client and that client had accepted a different list of transactions, it won't be able to claim the block.
sr. member
Activity: 266
Merit: 254
Building a multi source proxy in java, I haven't really got to the guts of verifying blockheaders yet but it's important to the design of the project to know if it matters.

i.e. say I'm taking getworks from multiple sources, when that getwork is solved and ready to be returned does it matter if I return it to a different bitcoin server or is the request somehow keyed to the bitcoin server that generated it?
Jump to: