solana-web3.js icon indicating copy to clipboard operation
solana-web3.js copied to clipboard

feat: Agave v2 RPC: replace `getRecentBlockhash` with `getLatestBlockhash`

Open buffalojoec opened this issue 1 year ago • 2 comments

buffalojoec avatar Oct 23 '24 05:10 buffalojoec

⚠️ No Changeset found

Latest commit: 6abe5864e361ab951618aa48e8088d742482d1a1

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

changeset-bot[bot] avatar Oct 23 '24 05:10 changeset-bot[bot]

This stack of pull requests is managed by Graphite. Learn more about stacking.

buffalojoec avatar Oct 23 '24 05:10 buffalojoec

What's our semver deal here, are we committed to backward compatibility across 1.x? I'd like to just remove the deprecated method TBH, but maybe we can't do that in a 1.x release. Failing that I'd prefer to just hardcode 5000, but not too worried either way.

mcintyre94 avatar Nov 01 '24 14:11 mcintyre94

What's our semver deal here, are we committed to backward compatibility across 1.x? I'd like to just remove the deprecated method TBH, but maybe we can't do that in a 1.x release. Failing that I'd prefer to just hardcode 5000, but not too worried either way.

We can't just remove them, even if they are deprecated. I can change this to be hard-coded, but we'd lose out on the fact that fees are supposed to change under varying network load. https://github.com/anza-xyz/agave/blob/96249691b4b7c873220b27376f271ead38392541/sdk/fee-calculator/src/lib.rs#L109

This might not be the prettiest solution, but it does capture fee rate changes with accuracy.

It's worth noting that the probability of someone using this field - on a long-deprecated method no less - is quite low.

@steveluscher what do you think here?

buffalojoec avatar Nov 08 '24 07:11 buffalojoec

OK, hear me out. How absolutely nuts would it be to:

  1. Deploy a program to mainnet/testnet/devnet that gave you the fee-per-signature as returnData
  2. Create a message that calls that program, having no blockhash
  3. Use simulateTransaction with that message, configured with replaceRecentBlockhash set to true
  4. Pull out the replacementBlockhash and returnData from that simulation

That way you could get this all done in a single call to the server.

steveluscher avatar Nov 12 '24 05:11 steveluscher

  1. Deploy a program to mainnet/testnet/devnet that gave you the fee-per-signature as returnData

How does a program get this info?

buffalojoec avatar Nov 12 '24 09:11 buffalojoec

How does a program get this info?

I was hoping you'd know better than me. This?

steveluscher avatar Nov 12 '24 21:11 steveluscher

How does a program get this info?

I was hoping you'd know better than me. This?

Actually I was tempted to use this and just load it from account data, but it's deprecated. So we can officially kick the can down the road and just load from a deprecated sysvar for now, and probably avoid the requirement for an on-chain program altogether.

https://github.com/anza-xyz/agave/blob/32b677bf4f2b4a718f62683e1daec87a3a83b83d/sdk/program/src/sysvar/fees.rs#L42 https://github.com/anza-xyz/agave/blob/32b677bf4f2b4a718f62683e1daec87a3a83b83d/sdk/fee-calculator/src/lib.rs#L23

This sysvar is still updated per-slot by Bank, so it would totally work (for now).

It would still be two calls, one to getLatestBlockhash and one to getAccountInfo to load the Fees sysvar and decode the lamports per signature. At least we wouldn't have to craft and serialize a message, though.

buffalojoec avatar Nov 13 '24 03:11 buffalojoec

It would still be two calls…

Well, the difference with that approach is that you could parallelize the calls, so that's much, much better than the implementation with serial calls. Go for it.

steveluscher avatar Nov 13 '24 20:11 steveluscher

@steveluscher the feature to disable the fees sysvar (JAN1trEUEtZjgXYzNBYHU9DYd7GnThhXfFP7SzPXkPsG) has been activated on all clusters.

The only way to get it properly loaded into the test validator is the hackery that is my second commit. The test validator's genesis config overwrites the account fixture if the feature is enabled.

If we still want to go this route, we just have to be aware that the sysvar's account itself hasn't been cleaned up on any higher clusters, but it's not being updated anymore.

buffalojoec avatar Nov 14 '24 16:11 buffalojoec

Oof. I'm not sure who we're building this for anymore.

  • The person who can't just switch to getFeeForMessage()
  • …but who is willing to upgrade all the way to the latest 1.x version

Surely that's nobody, right?

At this point I'm tempted to just:

return {
  context,
  value: {
    blockhash,
    feeCalculator: {
      get lamportsPerSignature() {
        throw new Error(
          'The capability to fetch `lamportsPerSignature` using the `getRecentBlockhash` API is ' +
          'no longer offered by the network. Use the `getFeeForMessage` API to obtain the fee ' +
          'for a given message.',
        );
      }
    },
  },
}

steveluscher avatar Nov 14 '24 18:11 steveluscher

Oof. I'm not sure who we're building this for anymore.

  • The person who can't just switch to getFeeForMessage()
  • …but who is willing to upgrade all the way to the latest 1.x version

Surely that's nobody, right?

At this point I'm tempted to just:

return {
  context,
  value: {
    blockhash,
    feeCalculator: {
      get lamportsPerSignature() {
        throw new Error(
          'The capability to fetch `lamportsPerSignature` using the `getRecentBlockhash` API is ' +
          'no longer offered by the network. Use the `getFeeForMessage` API to obtain the fee ' +
          'for a given message.',
        );
      }
    },
  },
}

Honestly this works for me. With this approach, we aren't technically breaking our API. However, the network simply doesn't support this field anymore, so they're going to get an error anyway. At least here we can vend a response for the endpoint, instead of the app getting an error outright (which it should).

buffalojoec avatar Nov 18 '24 10:11 buffalojoec

~Ship it, except you can't because you need to sign your commits now~.

steveluscher avatar Dec 06 '24 07:12 steveluscher

Merge activity

  • Dec 15, 11:14 PM EST: A user started a stack merge that includes this pull request via Graphite.
  • Dec 15, 11:18 PM EST: Graphite couldn't merge this pull request because a downstack PR #3418 failed to merge.

buffalojoec avatar Dec 16 '24 04:12 buffalojoec

:tada: This PR is included in version 1.98.0 :tada:

The release is available on:

Your semantic-release bot :package::rocket:

github-actions[bot] avatar Dec 16 '24 04:12 github-actions[bot]

Because there has been no activity on this PR for 14 days since it was merged, it has been automatically locked. Please open a new issue if it requires a follow up.

github-actions[bot] avatar Dec 30 '24 08:12 github-actions[bot]