New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for third-party, farmer-rewarded, Harvesters #16717
Conversation
Great stuff, but there's one issue, the harvester cannot blindly sign any message hash, it needs the original data for all messages that need to be signed:
If the harvester has an API to blindly sign message hashes, that API can be used to get a signature for a block header that does not give the dev fee. |
Good to see you, here @madMAx43v3r. I was going to reach out to you this week, so I'm happy to see that you're already involved here. I was assuming the validation of what was being signed would be determined by the harvester given the Please let me know if you have any more feedback. |
Ok so let me simplify the problem. Right now we essentially have an API for signing a message hash (array index 0) and an API for signing a data structure that can be validated (array index 1). What stops someone from using the API that doesnt validate anything and just signs the message hash for the message that is supposed be validated? You can simply bypass the validation. So yeah, unfortunately the harvester will need all the data structures to be signed in original form. Maybe they can be passed in serialized form, ie. byte array, to simplify the protocol. Since the message type information is not hashed, we have to rely on the serialized byte count to determine what kind of message it is. Not prepending a type string for the message hashes is really dangerous, but there's nothing we can do about it now, it's part of the consensus already. Even if you don't serialize the messages, you can still spoof the API into not validating the message that should be validated by using another message type and making it serialize to the same bytes, so the hash is what you need to be signed. This only works if another message has the same serialized size of course. Just saying, if the type information was included in the hash, this attack would not work. So now we have to be careful about message size collisions. If the message to be validated has a dynamic field that can take any size, like a string or byte array, then this whole idea will not work... Remember the CAT1 debacle was an attack of the same nature. For the random dev fee lottery I would just hash the |
Looking at the code again now, the message to be validated is
|
Yes But i's not important now since it's certainly reasonable to simplify it given your recommendation to include all the data, so I already made those changes yesterday. Anything being sent to the Harvester to sign will also contain the original data used to generate the hash that will be signed. The Harvester just need to request the original data be included when it sends its proof of space to the Farmer. I still have to update the tests to reflect the changes, though |
I don't think that would work. For example I could replace the signature request for the partial with the As long as there exists any path where you can get a signature for any hash, it allows to bypass the fee.
So a harvester with dev fee would then always set that bool to true right? |
Just saw your other commit. I missed
So got lucky again, no collision with In my implementation I will not sign any message that is 133 or 229 bytes and is not a validated |
I think you're right. The partial payload would make it troublesome.
That sounds good, is that what you currently do? We decided to let the Harvester itself take care of that without any convention agreement. We would simply display the stats to the user. The Harvester provider would not get locked-in into any convention this way and simplifies things from the Farmer side.
Yes, I also changed it so that a bool field can be specified here so that the farmer would include signing data even if the reward address will not be overwritten. Though overwriting the reward address also implies sending back source data for signing. Is there anything else that sticks out to you as troublesome from the current changes? |
No
That means an optional address field for the fee address in the proof response? I'm fine with that.
That's needed for sure, I wont sign anything without hashing all the data myself. Doing some if-else magic there is just asking for a loophole. |
Yes. Probably also specified whenever |
FYI @madMAx43v3r, it's supposed to be |
Yeah you right, those are 100 bytes, all good. |
There's a lot of challenge hashes and it's easy to get confused:
I'm not sure if you can simply change the The proper way would be to supply the Looking at the code now, |
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
Why have you decided to simplify it this way? Instead of just gathering statistics there can be a defined algorithm how to determine which block reward is going to be claimed by a harvester. |
I can confirm some people get paranoid when they are unlucky with the fee lottery. |
Requiring a specific mechanism to be used to determine which blocks have their reward diverted adds complexity and limits the freedom of the harvester. If one of you guys come up with some new clever scheme of picking blocks to divert, you would need an update to the protocol. The point of doing this, as you point out, would be that both the farmer and the harvester could check each other. However, it's not obvious what the best action would be, if a discrepancy is discovered. Refusing to sign, and squander the block-win doesn't help anyone. The farmer loses the fees and pool reward, the harvester loses its reward and the network loses netspace. It's kind of the "doomsday machine"-option; incentivize conformance through mutual destruction. I also think it has questionable value.
|
In current design the most obvious clever scheme is to cheat on user. For example a difference between 3% fee and a 5% fee is so tiny that only a really big miner can trace with a high confidence but for a harvester author it is a huge difference. The algorithm can be very simple and straightforward. Get the lower 32 bit of an sp_hash and compare it with a value
Not having a strict and deterministic reward distribution algorithm opens a room for social engineering attacks on competitors. Fanboys of a harvester author A will spam all over the internet that a harvester B is cheating and claiming bigger fee than it declares. We want to focus on programming and not spend resources on SMM. |
harvester and farmer for test_missing_messages`
Inject pre-generated signage points and blocks instead.
- Update valid fee quality test to be unit, instead of pseudo-integration. - New test for invalid fee quality. - More explicit messaging for invalid fee qualities. - Explicitly comment out uncovered case in test. - Update types for mypy.
ce0fe69
to
30c2f68
Compare
Conflicts have been resolved. A maintainer will review the pull request shortly. |
Anyone who wants to implement this CHIP will need it, since it's needed to verify what reward address has been set in the foliage block. It needs to be passed together with EDIT: Small correction, Just for reference, I've said this multiple times before (3 months ago):
|
OK sorry I missed it, I'll implement it |
@madMAx43v3r @nossdpool Additional work is being completed in PR #17435, which we intend to merge soon. |
@madMAx43v3r @nossdpool The code for CHIP-22 has all been merged. 2.2.0-rc3 is the first build to contain the complete CHIP. Please test it with your pools. |
This adds support for third-party Harvesters to be able to overwrite the farmer reward puzzle hash when it is time for them to take their reward, given a winning block.
Test overwrite address is respected and theUnifinishedBlock
includes it- [x]Timelord test requirement removed.install_timelord = True
must be enabled for new tests