cosmology-tech / telescope

A TypeScript Transpiler for Cosmos Protobufs ⚛️
https://cosmology.zone/products/telescope
Apache License 2.0
144 stars 43 forks source link

Log: invalid length: tx parse error #544

Open chalabi2 opened 8 months ago

chalabi2 commented 8 months ago

Context:

I am generating an amino message for the Gravity Bridge Fee Auction. The message generates, and I can sign/broadcast it just fine.

Issue:

Recently, one of the parameters which is required to submit the tx, BidFee, was raised. It was initially 3110 ugraviton but has been increased to 3110000000 ugraviton or 3110 graviton for short. After updating the parameter in the transaction, I am now getting

Error: Broadcasting transaction failed with code 2 (codespace: sdk). Log: invalid length: tx parse error

If i remove one digit from the fee number so instead of 3110000000 i use 311000000 it will sign and broadcast but ultimately fail as the chain will not accept any number lower then 3110000000.

I cant find anyone who's run into that error, and i'm having a hard time figuring out why that error appears. The issue is not with the chain or the transaction as I can sign and successfully broadcast the exact same transaction via cli and this was working before the fee change.

Any help or simply pointing me in the right direction would be awesome!

Link to successfully signed and broadcasted tx

Replicate

git clone https://github.com/chalabi2/auction-frontend
cd auction-frontend
npm install
npm run dev

OR Live Site

TX

export const bidOnAuction = (
  getSigningStargateClient: (
    signerOptions: SignerOptions
  ) => Promise<SigningStargateClient>,
  signerOptions: SignerOptions,
  setResp: (resp: string) => any,
  chainName: string,
  address: string,
  auctionId: string,
  bidAmount: string, 
  bidFeeAmount: string, 
  toast: ReturnType<typeof useToast>
) => {
  return async () => {
    const stargateClient = await getSigningStargateClient(signerOptions);
    if (!stargateClient || !address) {
      console.error("stargateClient undefined or address undefined.");
      return;
    }

    const { bid } = auction.v1.MessageComposer.withTypeUrl;

    const msg = bid({
      auctionId: BigInt(auctionId),
      bidder: address,
      amount: BigInt(bidAmount),
      bidFee: BigInt(bidFeeAmount),
    });

    const memo: string = "Submitted by Gravity Bridge Fee Auction App";

    const fee: StdFee = {
      gas: "1000000",
      amount: [
        {
          amount: "1000000",
          denom: "ugraviton",
        },
      ],
    };

    try {
      const response = await stargateClient.signAndBroadcast(
        address,
        [msg],
        fee,
        memo
      );
      setResp(JSON.stringify(response, null, 2));
      showSuccessToast(toast, response.transactionHash, chainName);
    } catch (error) {
      console.error("Error signing and sending transaction:", error);
      if (error instanceof Error) {
        showErrorToast(toast, error.message);
      }
    }
  };
};

This was an issue i posted in cosmjs and I was advised to contact the gravity bridge package maintainers which at this time is me.

My most up to date gravity bridge telescope generated package is here

Any advice on how i could generate types that allow me to use larger numbers would be much appreciated!

Zetazzz commented 8 months ago

Hi, sorry for the late response, let me take a look on this. Thank you very much for your feedback!

Zetazzz commented 8 months ago

Hi, here's my guess:

There're steps to encode and decode from stargate client to cosmos-sdk side:

  1. when stargateClient.signAndBroadcast gets msgs, it tries to encode msgs into {typeurl:"", value: uint8array} using a registered encoder.
  2. when cosmos-sdk got the encoded msgs, it will decode. From the error: "(codespace: sdk) invalid length: tx parse error", it means this error came from cosmos-sdk and happened when it’s decoding.

And I also noticed an interesting fact: 3110000000 is more than the max value of int32(2,147,483,647) and 311000000 is less.

So is there any possibility that the decoding process running on cosmos sdk side treated the field in int32 way? I understand that the proto file you provided said the field is int64. But how’s the code on cosmos-sdk side look like?

This’s just my guess, I think you can try values around (2,147,483,647) to test. If the value is not the boundary between success and failed, you still have to look into the logic on sdk side.

You can show me the repo(if there’s any) of auction on sdk side, so that I can help look into too.

Thank you very much!

chalabi2 commented 8 months ago

@Zetazzz Thank you for the detailed response.

My only concern with the theory of the sdk side of the auction module being the issue is that using CLI the transaction works as expected, of course CLI is using SIGN_DIRECT but it would be very helpful to get more eyes on the issue.

The sdk code for the auction module can be found here

https://github.com/Gravity-Bridge/Gravity-Bridge/tree/main/module/x/auction

Also just tested using 2147483647 for the bid fee and the transaction was signed and broadcasted but using 2147483648 generated the error we have been speaking about

Zetazzz commented 8 months ago

Hi, I remember once I encountered this error too, but not sure they're the same.

At the time, I encoded the msg before I transfer into signandbroadcast, meaning you can try this here:

// use this instead of 'withTypeUrl'
const { bid } = auction.v1.MessageComposer.encoded;

Not sure this will work to your case. My case was that the registered encoder to cosmjs was not the same as the encoder in my lib. So I have to encode using my own encoder to make sure the msg's encoded in a right way.

chalabi2 commented 8 months ago

Do you have an example of the manual encoding process?

Zetazzz commented 8 months ago

Do you have an example of the manual encoding process?

you can just replace 'withTypeUrl' function with 'encoded' function, not sure it will work at your case, but at least you can have a try.

// before
// const { bid } = auction.v1.MessageComposer.withTypeUrl;
// after
const { bid } = auction.v1.MessageComposer.encoded;

Difference between is withTypeUrl only wraps the msg object with typeurl and value, while 'encoded' wraps it with typeurl and value that's been encoded into uint8array.

chalabi2 commented 8 months ago

That makes the value section of the transaction data empty. It returns typeurl: gravity/MsgBid, value: {}

Zetazzz commented 8 months ago

That makes the value section of the transaction data empty. It returns typeurl: gravity/MsgBid, value: {}

Hi, I see. I think I made it wrong...

Btw, we just released the newest version of telescope 1.4.1 and cosmjs's also upgraded to 0.32, could you please to try new versions and see if there's any luck?