Error decoding contract event deployed with forc 0.63.5, fuel-core 0.35.0

Hi Fuel team!

I got a problem with docoding contract event(with fuels-ts 0.94.6):

[21:18:23.649] ERROR (41038): error decoding event
    chainId: 0
    logType: "Block Range Query"
    workerType: "HyperFuel"
    fromBlock: 0
    toBlock: 10800059
    addresses: [
      "0xafb6691ff311bb66067486481d7400d01faeef2f291fcfdda514e82d7230d027"
    ]
    fetchStateRegister: "root"
    blockNumber: 10782769
    logIndex: 1
    responsible event: {
      "blockHeight": 10782769,
      "blockTimestamp": 1726752468,
      "contractId": "0xafb6691ff311bb66067486481d7400d01faeef2f291fcfdda514e82d7230d027",
      "receipt": {
        "blockHeight": 10782769,
        "data": "0x0000000000989680336b7c06352a4b736ff6f688ba6885788b3df16e136e95310ade51aa32dc6f0500000000000000001ef4ca23f77ddd39400e32199f1e7e4a85dff2067a850ee0944ed6ece25c30fe00000000000000000000000000989680",
        "ra": 0,
        "rb": 12590297951544648000,
        "receiptIndex": 1,
        "receiptType": 6,
        "rootContractId": "0xafb6691ff311bb66067486481d7400d01faeef2f291fcfdda514e82d7230d027",
        "txId": "0x53d5c59000376e46cfac78be0d49b906bcd6b109bacc3310b32716b4aac98bdc",
        "txStatus": 0
      },
      "receiptIndex": 1,
      "receiptType": 6,
      "transactionId": "0x53d5c59000376e46cfac78be0d49b906bcd6b109bacc3310b32716b4aac98bdc"
    }
[21:18:23.651] ERROR (41038): Failed to parse event with Fuel, please double check your ABI.
    chainId: 0
    logType: "Block Range Query"
    workerType: "HyperFuel"
    fromBlock: 0
    toBlock: 10800059
    addresses: [
      "0xafb6691ff311bb66067486481d7400d01faeef2f291fcfdda514e82d7230d027"
    ]
    fetchStateRegister: "root"
    blockNumber: 10782769
    logIndex: 1
    err: {
      "type": "_FuelError",
      "message": "Invalid u64 byte data size.",
      "stack":
          FuelError: Invalid u64 byte data size.
              at BigNumberCoder.decode (/Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:453:13)
              at /Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:955:41
              at Array.reduce (<anonymous>)
              at _c.decode (/Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:952:51)
              at /Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:955:41
              at Array.reduce (<anonymous>)
              at _c.decode (/Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:952:51)
              at /Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:955:41
              at Array.reduce (<anonymous>)
              at _c.decode (/Users/master/spark-envio-indexer/generated/src/bindings/vendored-fuel-abi-coder.js:952:51)
      "VERSIONS": {
        "FORC": "0.63.5",
        "FUEL_CORE": "0.35.0",
        "FUELS": "0.94.6"
      },
      "metadata": {},
      "rawError": null,
      "code": "decode-error",
      "name": "FuelError"
    }

We recently had a similar problem and it was resolved with the release of fuels-ts 0.94.6:

it seems that the problem now is decoding the Account struct.

Could you please fix this and give us feedback? Thanks!!!

p.s. to visualize the changes on the Envio indexer side I created a pr:

Hey @PaulZhemanov, will look into it and get back to you

Just to confirm, did you redeploy your contracts with sway 0.63.6 and fuel-core 0.36.0? Also, can you share the steps to reproduce the error?

@Nazeeh21 Hi!

We modified the contract by adding struct Account inside all contract events.

pub balance: Account

You can see the changes on the contract here

I depoloyed this contract and supported the changes on the indexer side by replacing the new abi and contract id:

These are all the changes we’ve made. Thanks!

p.s. we tried the same using sway 0.63.6 and fuel-core 0.36.0 on the contract side.result is the same(

Hey @PaulZhemanov :wave:

I am taking a look into this now.

2 Likes

@PaulZhemanov are you certain this event is from the new contract deployment. As I can successfully decode the logged data with the old ABI.

Could you check and get back to me please?

This issue is very similar to the issue we had last week with fuels-ts. The fuels-ts 0.94.5 had a bug where the regex in the abi compiler got mixed up if the file name had the keyword “struct” in it. Maybe there is a similar issue since we are now logging a struct. When trying to decode the struct, we get this issue.

@p.s of course, you can see the changes to abi on both the contract and indexer side at the links above

1 Like

@p.s

What are the expected values from this log event?

in sway we use u64, but fuels-ts returns BigInt

1 Like

No - what is the expected data from the log data event, that you have posted.

What values do you expect as the decoded output?

pub struct DepositEvent {
    pub amount: u64,
    pub asset: AssetId,
    pub user: Identity,
    pub balance: Account,
}

we expect log like this

DepositEvent { amount: 86027600, asset: 0101010101010101010101010101010101010101010101010101010101010101, user: Address(95a7aa6cc32743f8706c40ef49a7423b47da763bb4bbc055b1f07254dc729036), balance: Account { liquid: Balance { base: 0, quote: 0 }, locked: Balance { base: 0, quote: 0 } } }

@p.s is there anything else I can do to help?

Is this a testnet address? I can’t find reference to it.

0x95a7aa6cc32743f8706c40ef49a7423b47da763bb4bbc055b1f07254dc729036

@p.s

I’ve removed the fields on the indexer side that use balance:
before debuggin:

 let event = new DepositEvent({
  id: receipt.receiptId,
  user: getIdentity(log.user),
  amount: BigInt(log.amount.toString()),
  baseAmount: BigInt(log.balance.liquid.base.toString()),
  quoteAmount: BigInt(log.balance.liquid.quote.toString()),
  asset: log.asset.bits,
  txId: receipt.txId,
  timestamp: tai64ToDate(receipt.time).toISOString(),
 })

after:

 let event = new DepositEvent({
  id: receipt.receiptId,
  user: getIdentity(log.user),
  amount: BigInt(log.amount.toString()),
  asset: log.asset.bits,
  txId: receipt.txId,
  timestamp: tai64ToDate(receipt.time).toISOString(),
 })

problem is the same…

I started debugging BigNumberCoder in node models

decode(data, offset) {
  console.log("Raw data:", data);
  console.log("Offset:", offset);
  console.log("Expected encoded length:", this.encodedLength);

  if (offset + this.encodedLength > data.length) {
    console.error(`Error: Offset (${offset}) plus expected length (${this.encodedLength}) exceeds data length (${data.length}).`);
    throw new import_errors4.FuelError(import_errors4.ErrorCode.DECODE_ERROR, `Data out of bounds for ${this.type} decoding.`);
  }

  let bytes = data.slice(offset, offset + this.encodedLength);
  console.log("Bytes after slicing:", bytes);

  if (bytes.length !== this.encodedLength) {
    console.error(`Error: Byte length (${bytes.length}) does not match expected encoded length (${this.encodedLength}).`);
    throw new import_errors4.FuelError(import_errors4.ErrorCode.DECODE_ERROR, `Invalid ${this.type} byte data size.`);
  }

  return [(0, import_math3.bn)(bytes), offset + this.encodedLength];
}

and i got this result

Raw data: Uint8Array(96) [
    0,   0,   0,   0,   0,   0,  39,  16,  56, 228, 202, 152,
   91,  34,  98,  95, 255, 147,  32,  94, 153, 123, 252,  92,
  200,  69,  58, 149,  61, 166,  56, 173,  41, 124, 166,  10,
  159,  38,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,
   30, 244, 202,  35, 247, 125, 221,  57,  64,  14,  50,  25,
  159,  30, 126,  74, 133, 223, 242,   6, 122, 133,  14, 224,
  148,  78, 214, 236, 226,  92,  48, 254,   0,   0,   0,   0,
    0,   0,  39,  16,   0,   0,   0,   0,   0,   0,   0,   0
]
Offset: 0
Expected encoded length: 8
Bytes after slicing: Uint8Array(8) [
  0, 0,  0,  0,
  0, 0, 39, 16
]
Raw data: Uint8Array(96) [
    0,   0,   0,   0,   0,   0,  39,  16,  56, 228, 202, 152,
   91,  34,  98,  95, 255, 147,  32,  94, 153, 123, 252,  92,
  200,  69,  58, 149,  61, 166,  56, 173,  41, 124, 166,  10,
  159,  38,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,
   30, 244, 202,  35, 247, 125, 221,  57,  64,  14,  50,  25,
  159,  30, 126,  74, 133, 223, 242,   6, 122, 133,  14, 224,
  148,  78, 214, 236, 226,  92,  48, 254,   0,   0,   0,   0,
    0,   0,  39,  16,   0,   0,   0,   0,   0,   0,   0,   0
]
Offset: 40
Expected encoded length: 8
Bytes after slicing: Uint8Array(8) [
  0, 0, 0, 0,
  0, 0, 0, 0
]
Raw data: Uint8Array(96) [
    0,   0,   0,   0,   0,   0,  39,  16,  56, 228, 202, 152,
   91,  34,  98,  95, 255, 147,  32,  94, 153, 123, 252,  92,
  200,  69,  58, 149,  61, 166,  56, 173,  41, 124, 166,  10,
  159,  38,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,
   30, 244, 202,  35, 247, 125, 221,  57,  64,  14,  50,  25,
  159,  30, 126,  74, 133, 223, 242,   6, 122, 133,  14, 224,
  148,  78, 214, 236, 226,  92,  48, 254,   0,   0,   0,   0,
    0,   0,  39,  16,   0,   0,   0,   0,   0,   0,   0,   0
]
Offset: 80
Expected encoded length: 8
Bytes after slicing: Uint8Array(8) [
  0, 0,  0,  0,
  0, 0, 39, 16
]
Raw data: Uint8Array(96) [
    0,   0,   0,   0,   0,   0,  39,  16,  56, 228, 202, 152,
   91,  34,  98,  95, 255, 147,  32,  94, 153, 123, 252,  92,
  200,  69,  58, 149,  61, 166,  56, 173,  41, 124, 166,  10,
  159,  38,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,
   30, 244, 202,  35, 247, 125, 221,  57,  64,  14,  50,  25,
  159,  30, 126,  74, 133, 223, 242,   6, 122, 133,  14, 224,
  148,  78, 214, 236, 226,  92,  48, 254,   0,   0,   0,   0,
    0,   0,  39,  16,   0,   0,   0,   0,   0,   0,   0,   0
]
Offset: 88
Expected encoded length: 8
Bytes after slicing: Uint8Array(8) [
  0, 0, 0, 0,
  0, 0, 0, 0
]
Raw data: Uint8Array(96) [
    0,   0,   0,   0,   0,   0,  39,  16,  56, 228, 202, 152,
   91,  34,  98,  95, 255, 147,  32,  94, 153, 123, 252,  92,
  200,  69,  58, 149,  61, 166,  56, 173,  41, 124, 166,  10,
  159,  38,   0, 188,   0,   0,   0,   0,   0,   0,   0,   0,
   30, 244, 202,  35, 247, 125, 221,  57,  64,  14,  50,  25,
  159,  30, 126,  74, 133, 223, 242,   6, 122, 133,  14, 224,
  148,  78, 214, 236, 226,  92,  48, 254,   0,   0,   0,   0,
    0,   0,  39,  16,   0,   0,   0,   0,   0,   0,   0,   0
]
Offset: 96
Expected encoded length: 8
Error: Offset (96) plus expected length (8) exceeds data length (96).

Can this get us closer to a solution? Please give feedback if I’m not clear or descriptive.

The account 0x95a7aa6cc32743f8706c40ef49a7423b47da763bb4bbc055b1f07254dc729036 you have provided does not exist.

I managed to partially decode your event and got the following results for the account and asset:

{
  asset: 0x336b7c06352a4b736ff6f688ba6885788b3df16e136e95310ade51aa32dc6f05,
  user: 0x1ef4ca23f77ddd39400e32199f1e7e4a85dff2067a850ee0944ed6ece25c30fe,
}

Which both reference an account and assets on the testnet.

hi! @p.s

DepositEvent { amount: 86027600, asset: 0101010101010101010101010101010101010101010101010101010101010101, user: Address(95a7aa6cc32743f8706c40ef49a7423b47da763bb4bbc055b1f07254dc729036), balance: Account { liquid: Balance { base: 0, quote: 0 }, locked: Balance { base: 0, quote: 0 } } }

this is just an example of a data structure. it’s not the transaction that’s the problem…

Could you give me the expected decoded values from this DepositEvent for this transaction (0x53d5c59000376e46cfac78be0d49b906bcd6b109bacc3310b32716b4aac98bdc)?

DepositEvent {
  amount: 10000000,
  asset: 0x336b7c06352a4b736ff6f688ba6885788b3df16e136e95310ade51aa32dc6f05,
  user: 0x1ef4ca23f77ddd39400e32199f1e7e4a85dff2067a850ee0944ed6ece25c30fe
  ),
  balance: Account {
    liquid: Balance {
      base: 0,
      quote: 10000000
    },
    locked: Balance {
      base: 0,
      quote: 0
    }
  }
}