paritytech / subxt

Interact with Substrate based nodes in Rust or WebAssembly
Other
390 stars 236 forks source link

`CheckMetadata` extension not working as expected #1639

Closed clangenb closed 3 weeks ago

clangenb commented 3 weeks ago

I have updated subxt to the latest version and regenerated the metadata.

I was expecting that it would just work like this:

let client = OnlineClient::<PolkadotConfig>::from_url(KUSAMA_URL).await?;

let tx = client
  .tx()
  .create_signed(<some_call>, <signed>, Default::default())
  .await?;

With the default extrinsic params as I was using before (when I read into the code, I believe this should be correct).

But I get the following error:

Transaction(Invalid("Transaction is invalid (eg because of a bad nonce, signature etc)"))

Am I misunderstanding something?

niklasad1 commented 3 weeks ago

@clangenb

Can you explain how you are generating the metadata and which chain your connecting to run into this?

clangenb commented 3 weeks ago

I was using two different endpoints, and I did it like this:

    #[subxt::subxt(
        runtime_metadata_insecure_url = "wss://kusama.api.onfinality.io/public-ws",
        derive_for_all_types = "Eq, PartialEq, Clone"
    )]
    pub mod runtime {}

But now that you say that. I will try generating a metadata file via the CLI and see if something changes.

clangenb commented 3 weeks ago

It doesn't change anything. Creating the metadata with:

subxt metadata -f bytes --url wss://kusama-rpc.polkadot.io:443 > metadata/kusama_metadata.scale

and changing the above to

    #[subxt::subxt(
        runtime_metadata_path = "../../metadata/kusama_metadata.scale",
        derive_for_all_types = "Eq, PartialEq, Clone"
    )]
    pub mod runtime {}

Results in the same error.

clangenb commented 3 weeks ago

The node seems to be able to decode the extrinsic and the mode is set correctly according to:

https://polkadot.js.org/apps/#/extrinsics/decode/0x11048400b06c021615bf00ced6ccd77c0bc8c820a71e819bfc48dff36ffb12d7ba04433801b28d4aac516ce747ca5ce82ddc76cb71987eb754d88ea0bababafcda99da4967c4c7bc9d5b2fd582bdaad67a4ad0688e4568d21d918c8bfa2d5afa351c7eef888400ad4e0000180010061274c76b2bb6e2e4b16fec1849aefadeae913aed26e72e2101a4dc34abb3e40776491a0000061274c76b2bb6e2e4b16fec1849aefadeae913aed26e72e2101a4dc34abb3e407764a1a0000061274c76b2bb6e2e4b16fec1849aefadeae913aed26e72e2101a4dc34abb3e407764b1a0000061274c76b2bb6e2e4b16fec1849aefadeae913aed26e72e2101a4dc34abb3e407764c1a0000

jsdw commented 3 weeks ago

Just to check though, because you mention some different URLs eg wss://kusama.api.onfinality.io/public-ws and wss://kusama-rpc.polkadot.io:443 to create metadata and then in the code snippet you actually connect subxt to POLKADOT_URL... what is POLKADOT_URL?

Because PJS decodes the extrinsic above happily on Kusama but not on Polkadot (I'm not quite sure why because I thought CheckMetadataHash is now live on Polkadot, but could be some difference), so I'd make sure to use metadata from the same relay chain you want to connect to.

clangenb commented 3 weeks ago

Sorry for the confusion. The snipped form above was copied from the wrong file (I have edited it now to prevent further confusion.)

I am sending it to the very same endpoint I have used to generate the metadata: pub const KUSAMA_URL: &'static str = "wss://kusama-rpc.polkadot.io:443"; Only once I tried to change the metadata endpoint to onfinality to see if there is a different result.

Sidenote: Polkadot is still on runtimes v1.2.4, which is why the CheckMetadataHash extension is not yet life there, it has been introduced with v1.2.5.

I am sorry to say that this repo is unfortunately private, so I can't share more😞

clangenb commented 3 weeks ago

It could be related to batch transactions, I successfully run this code on a chopsticks fork:

    #[tokio::test]
    async fn test_send_tx() {
        let api = OnlineClient::<PolkadotConfig>::from_url("ws://localhost:8001").await.unwrap();
        let alice = sp_keyring::Sr25519Keyring::Alice;
        let bob = sp_keyring::Sr25519Keyring::Bob;

        let signer = PairSigner::new(alice.pair());

        let call = kusama::tx()
            .balances()
            .transfer_keep_alive(bob.to_account_id().into(), 1_000_000_000);

        let tx = api.tx().create_signed(&call, &signer, Default::default()).await.unwrap();

        tx.submit_and_watch().await.unwrap().wait_for_finalized_success().await.unwrap();
    }

Or it might be my code. I will close this issue for now until I have ruled out that the issue is on my end.

Thanks for your support. 👍