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
Can we replace LastBlockID in Header with LastBlockHash ? #1605
Comments
Also what's the reason for the hash of the header to be a merkle tree of its components ? Is that really worth it when we could simply amino hash the header as is ? Ideally the binary encoding of the header is effectively a protobuf encoding - that would be the simplest thing |
Regarding BlockID, seems reasonable what you are saying. I guess that the role of this field is just to link block at height h with a block at height h-1. For this purpose, hash should do the job, so BlockID is not needed. Regarding the second question, when we need to prove something (for example with light client or IBC) do we need header to serve as a root hash, or it is sufficient having several root hashes for different aspects of the system. My understanding is that it's not really needed as we prove that header is valid by checking LastCommit, and then we validated various root hashes (validator set, app hash, etc). |
right, which means we need to hash the header to check the signature. I'm just proposing we make "hash the header" as simple as possible by making it a simple sha256 of the protobuf encoding! |
Understood this. Seems like sha256 of the protobuf encoding is fine. |
Ok, so the reason the votes need to sign the BlockID is so that peers can securely download a block using the block-part mechanism just from seeing a commit. This also means the consensus reactor can help catch up old peers by gossiping block-parts (unlike the blockchain reactor sending whole blocks). Then since the votes sign the BlockID, you need to know the BlockID to verify a commit. Currently the BlockID is in the commit votes and the header, but since we plan to remove it from the commit votes (#1648 ), we'd have to store it somewhere else in the block. It could be in the This also allows us to use the block-part mechanism to securely catchup peers in the consensus reactor - once they verify a commit, they can securely download block parts from different peers because they know the whole BlockID. If we wanted to get rid of BlockID, we'd probably have to do something like elevate the use of Proposals - you'd need to have the proposal and the commit to download blocks using the block-part mechanism. This is probably not worth the complexity in the short term, but interesting to consider. |
Ok, so it seems we have several different concerns here.
To sum up, I think that we can replace LastBlockID in the block header with LastBlockHash, and that the hash of the header can be simple sha256 of the protobuf encoding of the header. |
We still need the BlockID to verify commits though - if we remove it from the Header, it still has to be present in the block otherwise no one will be able to verify commits! |
The question was if we can replace LastBlockId with LastBlockHash. We do need to have BlockId in the block in case we want to support SWIFT dissemination. Could you please be more precise what do you mean by verifying commits? |
Commits are a list of |
We could replace BlockID with BlockHash in the header, but then we'd need to make sure the BlockID is still present in the block somehow so the votes can be verified. Since that's the case, it doesn't really feel worth it to remove it from the header... As for the hash of the header, I think the argument is that if a light client wants to verify something in the header, it doesn't need the whole header (which could be a few hundred bytes) but just the field it's interested in and the Merkle proof. So using a Merkle tree here instead of a raw hash might save a few hundred bytes, but as soon as you want to verify more than one field in the header, those savings probably disappear ... |
The gain of removing BlockID from header is small in terms of bytes, but maybe it is cleaner like this. |
So I think in conclusion we are not going to remove the BlockID, so nothing will change here. We should definitely better document why it's there and why we need it. |
Can we create a follow-up issue and close this? |
Here is the issue: https://github.com/tendermint/tendermint/issues/2373. |
* ADR 109: Internalize specific packages to reduce surface area (tendermint#1485) * consensus: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * evidence: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * inspect: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * state: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * blocksync: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * statesync: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * store: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/async: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/autofile: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/bits: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/clist: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/cmap: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/events: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/fail: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/flowrate: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/os: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/progressbar: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/protoio: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/pubsub: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/net: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/rand: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/service: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/strings: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/sync: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/tempfile: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * libs/timer: Move into internal Signed-off-by: Thane Thomson <connect@thanethomson.com> * Add changelog entries Signed-off-by: Thane Thomson <connect@thanethomson.com> --------- Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR 109: Modularize test infra (tendermint#1488) * test/e2e: Split out as separate module Signed-off-by: Thane Thomson <connect@thanethomson.com> * test/loadtime: Split out as separate module Signed-off-by: Thane Thomson <connect@thanethomson.com> * test/e2e: Remove optimization from Docker image construction Signed-off-by: Thane Thomson <connect@thanethomson.com> * Ensure that linter covers E2E framework and app Signed-off-by: Thane Thomson <connect@thanethomson.com> * Update CI linting to cover submodules Signed-off-by: Thane Thomson <connect@thanethomson.com> * Add changelog entry Signed-off-by: Thane Thomson <connect@thanethomson.com> * Expand linter coverage to loadtime tool Signed-off-by: Thane Thomson <connect@thanethomson.com> * Add missing phony entries Signed-off-by: Thane Thomson <connect@thanethomson.com> * test/e2e: Sync debug Dockerfile with primary Dockerfile Signed-off-by: Thane Thomson <connect@thanethomson.com> --------- Signed-off-by: Thane Thomson <connect@thanethomson.com> * chore: ADR 109: go mod tidy (tendermint#1606) * go mod tidy Signed-off-by: Thane Thomson <connect@thanethomson.com> * go.mod: Remove patch version Signed-off-by: Thane Thomson <connect@thanethomson.com> * go.mod: Remove new toolchain directives Signed-off-by: Thane Thomson <connect@thanethomson.com> --------- Signed-off-by: Thane Thomson <connect@thanethomson.com> * ADR 109: Fix mock generation (tendermint#1607) * internal: Fix mockery code generation script paths Signed-off-by: Thane Thomson <connect@thanethomson.com> * make mockery Signed-off-by: Thane Thomson <connect@thanethomson.com> --------- Signed-off-by: Thane Thomson <connect@thanethomson.com> --------- Signed-off-by: Thane Thomson <connect@thanethomson.com>
Is there some reason we need the BlockID in the Header? From what I understand, we only need it in the proposal to support the SWIFT like gossiping. I don't immediately see why we would need the next block to include a commitment to the way the last block was gossiped.
@jaekwon @milosevic
The text was updated successfully, but these errors were encountered: