cosmos / cosmos-sdk

:chains: A Framework for Building High Value Public Blockchains :sparkles:
https://cosmos.network/
Apache License 2.0
6.1k stars 3.53k forks source link

Bug: `sdk_block` translated proposer address is wrong #14079

Closed minxylynx closed 1 year ago

minxylynx commented 1 year ago

Summary of Bug

The GetBlockByHeightResponse.sdk_block.header.proposer_address does not match the actual proposer address

Version

0.46.6

Steps to Reproduce

Taking a block, like https://api.test.provenance.io/cosmos/base/tendermint/v1beta1/blocks/11673901, compare the GetBlockByHeightResponse.sdk_block.header.proposer_address (the translated address) to the actual address derived from the GetBlockByHeightResponse.block.header.proposer_address (the bytes).

The problem arises in that the proposer_address bytes should translate to the validator's _consensusaddress (ie. pbvalcons), not the _operatoraddress (ie. pbvaloper). Using the proposer_address bytes, you need to perform the following steps to find the actual proposer operator address: 1) proposer_address bytes -> derived validator consensus address

2) EITHER a) for all (any) validator records, using the consensus_pubkey object, derive the matching consensus address ~b) OR using the derived validator consensus address from (1), derive the consensus pubkey object~ Not easy, just ignore this option

  1. EITHER a) match derived validator consensus address from (1) to a derived consensus address from (2a) to get the matching validator record ~b) OR match the derived consensus pubkey from (2b) to a validator record containing the same pubkey object~ As 2b isnt necessary, just ignore this option

4) Use the real validator operator address from the matching validator record from (3a) or (3b)

Example, using the URL from before

1) proposer_address bytes                                 = CF53B691AFA2EB28C3D2AE118EF8F88FC48459BC
   derived validator consensus address                    = tpvalcons1eafmdyd05t4j3s7j4cgca78c3lzggkdujfqlv5

2a) validator consensus_pubkey                       = '@type': /cosmos.crypto.ed25519.PubKey, key: ynN46KrMfGdSvaT7jam8c+qVxyBHyuLhIT+dRLZufk0=
    derived matching consensus address               = tpvalcons1eafmdyd05t4j3s7j4cgca78c3lzggkdujfqlv5

3a) derived validator consensus address == derived matching consensus address
    matching validator  = tpvaloper1x299m72h6n88sswg2p9fp8lvkhrtqsvvv3rxsd

OR

2b) derived validator consensus address         = tpvalcons1eafmdyd05t4j3s7j4cgca78c3lzggkdujfqlv5
    derived consensus_pubkey                    = '@type': /cosmos.crypto.ed25519.PubKey, key: ynN46KrMfGdSvaT7jam8c+qVxyBHyuLhIT+dRLZufk0=

3b) derived consensus_pubkey == matching validator consensus pubkey
    matching validator  = tpvaloper1x299m72h6n88sswg2p9fp8lvkhrtqsvvv3rxsd

Note that the proposer_address as seen in the sdk_block object does not match "proposer_address": "tpvaloper1eafmdyd05t4j3s7j4cgca78c3lzggkdux6nrq4"

alexanderbez commented 1 year ago

Why is there an sdk_block field to begin with? When/why was that added?

tac0turtle commented 1 year ago

Why is there an sdk_block field to begin with? When/why was that added?

in order to assist users in providing a decoded block instead of needing to decode themselves. There was an issue asking for this

atheeshp commented 1 year ago

Why is there an sdk_block field to begin with? When/why was that added?

https://github.com/cosmos/cosmos-sdk/pull/11390 it's added here, I may have a look on this.

atheeshp commented 1 year ago

@minxylynx

1) proposer_address bytes -> derived validator consensus address

  2) EITHER 
a)  for all (any) validator records, using the consensus_pubkey object, derive the matching consensus address
 b) OR using the derived validator consensus address from (1), derive the consensus pubkey object

  3. EITHER 
  a) match derived validator consensus address from (1) to a derived consensus address from (2a) to get the matching validator record
  b) OR match the derived consensus pubkey from (2b) to a validator record containing the same pubkey object

4) Use the real validator operator address from the matching validator record from (3a) or (3b)

Q1: How can we get the consensus pubkey object from consensus address (2b)? Q2: In 3b how do we get the validator records to match? should we call the grpc?

minxylynx commented 1 year ago

@atheeshp

Truth be told, I never go from consensus address to consensus pubkey. Its just easier to match at the address. So id recommend deriving the address from the pubkey, and then matching on the addresses.

As for your Q2, the validator object has a consensus_pubkey field. You'd have to cycle through all the validators to derive the consensus address from of the validator object, and then match on the derived proposer address.

Sorry if thats not the answer you wanted.

atheeshp commented 1 year ago

As for your Q2, the validator object has a consensus_pubkey field. You'd have to cycle through all the validators to derive the consensus address from of the validator object, and then match on the derived proposer address.

@minxylynx Thanks for the clarification here, but I think we may not able fetch all validators info from this helper since it doesn't have state access from there.