Remove `get-block-winner` and related map
Closed this issue · 3 comments
The original protocol had two ways of figuring out a winner for a given block.
is-block-winner
that checks the values against the VRF and returns true/false if user is winnercan-claim-mining-reward
that's the same as above, but returns true/false if user can claimget-block-winner
which returns the winning ID for a block after it's been claimed
That last detail has caused some confusion - I know sites like miamining.com usually try it first, then fall back on searching through the miners one by one to find the winner.
In this version of the protocol, is-block-winner
and can-claim-mining-reward
are combined into one function that return a tuple.
My question is for the front end integrations - is that enough to gather data on the winners?
Do we need get-block-winner
and does it provide any advantage?
I also think some of this could be mitigated by a caching strategy, where a middle layer would do these type of searches using a cron job, populate the data, then serve that to the website.
sip015.xyz was able to achieve this through Workers + KV: indexer, api, front-end. If we could follow similar patterns here, it would eliminate the extra work of finding the winner at each block.
Tagging @BowTiedMooneeb @friedger @Jamil who've worked with this logic, please tag others if you think of them as well.
The method used to get the block winner from is-block-winner
was much more inefficient than it should have been for miamining, basically for each block I’d have to iterate over all the potential winners, and then find which one was the actual winner.
Would definitely ideally have a get-block-winner
that returns the winner if one exists, even if they haven’t claimed the reward. Though I understand this may be computationally intractable from the smart contract side.
I still think get-block-winner
is useful if that’s not possible, since for the vast majority of historical blocks, it’ll be easy to fetch the winner in one call - though the function should be renamed if it only returns the winner if claimed.
The method used to get the block winner from is-block-winner was much more inefficient than it should have been for miamining, basically for each block I’d have to iterate over all the potential winners, and then find which one was the actual winner.
This is where I think a better caching strategy could help, after 100 blocks pass (the maturity window), the history is finalized so it could be queried and stored for quick retrieval. To me it feels like is-block-winner
is more consistent than get-block-winner
since the latter relies on the miner making a claim.
Would definitely ideally have a get-block-winner that returns the winner if one exists, even if they haven’t claimed the reward. Though I understand this may be computationally intractable from the smart contract side.
I agree this would be great! The trouble was two-fold: read-only contract functions have pretty low execution limits compared to public functions, and writing to the map would require a public function call.
We explored tying this into other operations of the protocol but given the cross-contract nature and the fact we're tracking data per city in this iteration, there isn't room to add any additional costs. They need to be as low as possible.
Under the hood, is-block-winner
gets the same values that claim-mining-reward
would to determine the winner, so it's the most reliable, but it cannot save the information once known.
I still think get-block-winner is useful if that’s not possible, since for the vast majority of historical blocks, it’ll be easy to fetch the winner in one call - though the function should be renamed if it only returns the winner if claimed.
That's a good point - maybe just rename it so it's better understood, something like get-block-winner-if-claimed
. I do like how it's one query, but it'd also be nice to drop off one map from the read/write budget and serve something like this from a middle layer.
The CityCoins API uses Cloudflare already so it'd just be a matter of adding an indexer, and that data could be consumed by any front-end service. It also gives us the opportunity to group multiple tasks, e.g. get the user ID from the principal, query with the user ID, apply logic based on the result, and return data without putting too much burden on the smart contract side.
After testing this against the costs of the contract the difference was negligible, so it's not going anywhere!