Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support serializing/deserializing StaticTxPayload #637

Closed
trusch opened this issue Aug 25, 2022 · 7 comments
Closed

Support serializing/deserializing StaticTxPayload #637

trusch opened this issue Aug 25, 2022 · 7 comments

Comments

@trusch
Copy link

trusch commented Aug 25, 2022

I'd like to create an extrinsic, serialize and transmit to another computer and then deserialize it again to submit it to the chain.

If I take for example this 0x000110deadbeef (which is what polkadot.js gives me for system::remark(0xdeadbeef)) I'd like to parse it into a StaticTxPayload so I can submit it.

Is this possible?

@trusch
Copy link
Author

trusch commented Aug 25, 2022

I tried this, but it gives me an error when submitting the extrinsic:

struct RawCall(Vec<u8>);

impl TxPayload for RawCall {
    fn pallet_name(&self) -> &str {
        ""
    }

    fn call_name(&self) -> &str {
        ""
    }

    fn encode_call_data(
            &self,
            _: &subxt::Metadata,
            out: &mut Vec<u8>,
        ) -> Result<(), subxt::Error> {
        out.extend_from_slice(&self.0);
        Ok(())
    }
}

...

let call_data = "0x000110deadbeef";
let call_bs = hex::decode(call_data.trim_start_matches("0x"))?;    
let payload = RawCall(call_bs);
let progress = cli.tx().sign_and_submit_then_watch_default(&payload, &signer).await.map_err(|err|Error::Chain(err))?;

Error is this:

Chain(Rpc(Call(Custom(ErrorObject { code: ServerError(1002), message: "Verification Error: Runtime error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\nWASM backtrace:\n\n    0: 0x3ef3c - <unknown>!rust_begin_unwind\n    1: 0x3995 - <unknown>!core::panicking::panic_fmt::h5118e89563022e7e\n    2: 0x259f9a - <unknown>!TaggedTransactionQueue_validate_transaction\n", data: Some(RawValue("Runtime error: Execution failed: Execution aborted due to trap: wasm trap: wasm `unreachable` instruction executed\nWASM backtrace:\n\n    0: 0x3ef3c - <unknown>!rust_begin_unwind\n    1: 0x3995 - <unknown>!core::panicking::panic_fmt::h5118e89563022e7e\n    2: 0x259f9a - <unknown>!TaggedTransactionQueue_validate_transaction\n")) }))))

@jsdw
Copy link
Collaborator

jsdw commented Aug 25, 2022

I'll have a look into this, because it makes me wonder whether the TxPayload interface could be tweaked. Lemme get back to you!

@jsdw
Copy link
Collaborator

jsdw commented Aug 25, 2022

Ok, so your implementation of TxPayload looks perfectly sane to me, and would be the way to allow pre-encoded call data to be provided again (I did push a small PR to simplify the TxPayload trait, since for transactions specifically (as opposed to storage and constants) we don't need the pallet and call names at all unless validating).

The error you get back is odd, and my guess offhand is that it's not an issue with subxt submitting the data, but instead is some issue with how the node is handling it (a wasm trap makes it sound like something in the runtime is having issues to me).

To test, can you encode and submit the same call using the normal statically generated polkadot::tx().system().remark(..) approach?

@trusch
Copy link
Author

trusch commented Aug 25, 2022

At least the encoding is the same.

let call2 = bte_service::kilt::tx().system().remark(vec![0xde, 0xad, 0xbe, 0xef]);
let cli = bte_service::kilt::connect("wss://spiritnet.kilt.io:443").await?;
let mut out = vec![];
call2.encode_call_data(&cli.metadata(), &mut out)?;
println!("call2: 0x{}", hex::encode(&out));

prints 0x000110deadbeef

I'll try if perhaps remarks are broken in our chain.

Thank you very much already :)

@jsdw
Copy link
Collaborator

jsdw commented Aug 25, 2022

Okeydoke, thanks!

In the meantime I hopefully made it a bit easier to do this sort of thing in #638 (with call data or with a fully signed transaction that you want to save and run later).

@trusch
Copy link
Author

trusch commented Aug 26, 2022

It also doesn't work for me when submitting it directly, so I think its unrelated to the serialization/deserialization. I guess its something else in the 0.22-0.23 update then, I'll keep searching :)

Only one remark as a user feedback: It would have been nice if coded::{Encode,Decode} would be implemented on the StaticTxPayload object or if subxt would come with a wrapper for this type which implements this. The actual CallData inside is already Encode. This would made it obvious how to serialize/deserialize a transaction.

@trusch
Copy link
Author

trusch commented Aug 30, 2022

@jsdw It turned out I had to use PolkadotExtrinsicParams and not SubstrateExtrinsicParams. They only differ in the Tip structure. If anybody runs into similar issues, give it a try!

@trusch trusch closed this as completed Aug 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants