Finding block's proposer with new API V2

Hi there,

it is not clear to me how to get block’s proposer with the new API V2, it was pretty easy with API V1. Is there a way to do it easly with the new API V2 too?

It is a pity to lose such features, are very useful to easly analize the PPoS decentralization rate. I think the development process should facilitate this kind of query, making easier and easier to collect these stats.

I think this new API V2 privileges the use of Archival Full Nodes or third party APIs. The old “Light Node” architecture was a very good trade off between versatility and hardware resources. I was able to do pretty much everything just with a simple Raspberry Pi, I believe this kind of approch pushed in the direction of greater decentralization.

What do you think about it?

1 Like

@cusma,

The intent of the REST API was always to support the user-facing features around the blockchain functionality and hide the underlying operational infrastructure. The rationale here is that a good API is one that doesn’t need to be change often, and underlying changes can be made without negatively affect all the potential user base.

At some point, there will be always some individuals that would need more customized functionality. That’s where our open source platform comes handy. You can see for yourself why these decisions around the API were made, and have a complete ability to customize it for your needs.

Regarding the Raspberry PI computing platform, please note that Algorand never intended to support that platform as an archival and/or indexer node. This (weaker) platform was only supported as a non-archival, non-indexer node, which is capable of participating in the consensus. Note that I’m not sure how well it would work if and when the Algorand network would reach it’s high-end transactional capacity ( i.e. I’m pretty sure it would not be capable of supporting the network at that time )

Specifically regarding to your issue, could you please specify which REST endpoint to used to use on V1, and which corresponding REST endpoint is no longer supporting the desired equivalent functionality ?

thanks!

Hi @tsachi, thanks for the clarification,

I was reffering to “proposer” inside block information.

Regarding the Raspberry Pi platform, to date I developed using my non-archival and non-indexer node.

V2 no longer has BlockRaw for one.
The Block response from Block() also no longer has proposer.
With BlockRaw you could at least decode it and get access to the Cert portion of the overall block.

Given that a non-archival node has to have all data for the blocks it processes to participate in the first place, there’s no reason for the API to not provide all access to all accessible data. For a non-archival node that’s at least the last 1000 blocks.
Just because the new indexer doesn’t care about the proposer or the voters (from the cert block) doesn’t mean it’s not critical information.

Honestly, no longer exposing the proposer of a block which is so fundamental to the security of a blockchain, I’m pretty shocked at its removal.

I think any chain explorer site or local project should be able to be implemented solely by data obtained from the client API and a local node. I have a local scanner that watches blocks for proposal wins or on-chain, confirmed votes from the specified address. It also tracks unique voters, proposers, etc. I have to use BlockRaw to get it - but I can still get it. The indexer does the same thing (not using the v2 api btw!).

Re. comments about it never being an intention to be lightweight - I’m with @cusma. The simple requirements of a non archival node are one of Algorand’s draws - and from information I recall, one of the things touted for it. TEAL vs EVM, VRF verification of proposers, etc.

…basically, everything you see via goal ledger block XX should be accessible via the algorand client sdk if the specified block has yet to be pruned from the local node. The base ‘Block’ response should contain everything from ‘block’ and not be a cut-down version. I’m not sure why it was chosen to cut that back.

If you wanted to limit return size, allowing response filtering like ElasticSearch is one option: https://www.elastic.co/guide/en/elasticsearch/reference/current/common-options.html#common-options-response-filtering

Perhaps something simpler like a default simple response vs a ?full response.

Did any solution to removed proposer arise?

1 Like

Hi @cusma @Tim although an old post, let me answer.

In order to get the proposer, you must get the block in msgpack format which includes certificate information (part of the consensus agreement).

2 Likes

This is a huge fail in the v2 apis. I’m not a fan of them to be honest.
There’s nothing exposed in the client sdks to unpack this cleanly. I had to pull transcode/core.go code out of the main algorand/ repo to cleanly extract the msgpack data into a json struct.
calling like:
err = transcode.Transcode(true, true, false, in, out)
to extract as base32 (format of Algorand account addresses).
I then had to define my own raw block structure (since the ‘real’ one isn’t exported) pulled from the algoand code - and unmarshal into that.

The accounts are also missing the 4 byte checksums so they’re not the user-exposed Account address and the SDKs provide no means of converting from it.

So I had to hack around that as well with something like this:

func rawAddressAsAddress(rawAddress string) types.Address {
	address, err := base32.StdEncoding.DecodeString(rawAddress)
	if err != nil {
		log.Fatalln(err)
	}
	dgst := types.Digest{}
	copy(dgst[:], address[:])

	return types.Address(dgst)
}

Then the proposal winner was accessible as the full proper Algorand Account via:
proposer := rawAddressAsAddress(block.Cert.Prop.Oprop).String()

2 Likes

Thanks for both the answers - we’ll take a look at the msgpack data and see how we want to handle displaying proposer (or just don’t show it any longer).

Just for the sake of completeness if somebody comes to this thread, here is the way to get the proposer with the JS SDK:

const algosdk = require("algosdk");

const c = new algosdk.Algodv2("", "https://testnet.algoexplorerapi.io", "");

(async () => {
  const blk = await c.block(13819291).do();
  const proposer = algosdk.encodeAddress(blk["cert"]["prop"]["oprop"]);
  console.log(proposer);
})();

Other SDKs work similarly, the client methods are: GetBlock for Java, block_raw for Python, BlockRaw for Go.

2 Likes