[Solved] Error code -32603 on channel Close

Hi guys,

I am facing an issue when closing the channel. The issue seems to be intermittent. the error is:

Error: Unexpected message received:

{"channel_id":"ch_2HRuMdeEhbVNTs79hYReLtZhrwvBBtjbR9ojRh5Dq8bKNWSpk9","error":{"code":-32603,"message":"Internal error","request":{"jsonrpc":"2.0","method":"channels.shutdown","params":{}}},"id":null,"jsonrpc":"2.0","version":1}

This happens when I call the shutDown(). Here is how I am calling:

           const account = new Account(keypair, this.network) //custom class to get sdkInstance
            const wallet = await account.wallet()
            const result = await channel.shutdown(
                async (tx) => await wallet.signTransaction(tx)
            )

What am I missing , any idea?

TIA

Hi @vishwas_hypermine this looks like a node issue. Can you please check the node’s logs? You’re looking for an error there. My bet is on a timeout :slight_smile:

Sorry for late reply. I noticed that there is error like Error: State Channels FSM entered unknown state any idea about why does it comes?

Yes, it is when the SDK receives something unexpected. cc @nduchak.chain

@vishwas_hypermine I would still like to see some node log errors. How are you running your node? Is it a docker image?

yes in docker. can you please guide me to see the logs. by the way I also tried on test network and this error is quit frequent over there

@vishwas_hypermine Can’t we do

docker ps and then docker log -f containerid ??

1 Like

image

@dimitar.chain this is log I am seeing. There is no other message except Closing channel message received

When I get the above message in the node log, I get the following error response when calling .close().

Unexpected message received:\n\n{\"channel_id\":\"ch_2fz1BLgxNA4wzz5AVVGQ1Lvco8TpB3Kp34uiwQpGXZ3xv9xUa3\",\"error\":{\"code\":-32603,\"message\":\"Internal error\",\"request\":{\"jsonrpc\":\"2.0\",\"method\":\"channels.shutdown\",\"params\":{}}},\"id\":null,\"jsonrpc\":\"2.0\",\"version\":1}

But sometime I see this error log as well (but this is very rare)

And in the .close() response I get the following transaction:

tx_+OQLAfiEuEAV0PV7/lKpB+Tfn5A2OKxH2TnEJEsXYtLByZ/0LOGa1CzEQkV1vKZ+UrQkOU9RdM2zfbTvGTac42DOuUiA1H8FuED2DCQgszBZu7B+sEmjfqlqxXUGn1icMsK7DOKOBowaqQRyWo4KrbM6S+g5pPKrjbw3Mn8i2ixRdlLjQMys73gIuFr4WDUBoQbon8u1tDAoHsNpl4hLa8CSRjdSCM7NYuC3OFikUgq+rqEB6bv2BOYRtUYKOzmZ6Xcbb2BBfXPOfFUZ4S9+EnoSJcqHEbFImvtAAAAAhhIwnOVAAAw2HFQi

Guys there seems to be a bug. Take a look at the state of channel just before I close it

Here you can see the balances of initiator (ak_2mwRmUeYmfuW93ti9HMSUJzCk1EYcQEfikVSzgo6k2VghsWhgU) and responder (ak_fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk) as 4999999999997000 and 3000 respectively.

Now take a look at the signed decoded transaction after calling close()

How can responderAmountFinal is 0. It should be 3000 right?

Also note that the above response of close() is rare, and mostly I get the Unexpected message received error

Guys, I think I got the root cause of this issue.

If you look at the amount which I was passing, I think it is so less that when closing the channel you can’t even pay the fee and hence giving the error: Unexpected message received although this error should be proper message.

{
  url: 'ws://localhost:3001/channel',
  initiatorId: 'ak_fUq2NesPXcYZ1CcqBcGC3StpdnQw3iVxMA3YSeCNAwfN4myQk',
  responderId: 'ak_2mwRmUeYmfuW93ti9HMSUJzCk1EYcQEfikVSzgo6k2VghsWhgU',
  initiatorAmount: '5000',
  responderAmount: '1000',
  pushAmount: 0,
  channelReserve: 0,
  ttl: 1000,
  host: 'localhost',
  port: '3000',
  lockPeriod: 10,
  minimumDepth: 0,
  role: 'responder'
}

Now if I provide the responder fee as 0 the channel is still able to create. Which in my pooint of view, should not. It should give me error which creating the channel itself that there should be some minimum deposite amount that both the peers has to provide.

See I am able to create a channel even if one of the peer amount is 0

My Suggestion: What I feel is there should be proper validation of config param before creating the channel. I think we can do it on JS-SDK side otherwise the money will get stuck into the channel forever. (I understand there is way to handle this problem using deposit but still)

Maybe I am totally getting you wrong, but to my knowledge the channel close tx is not paid from the deposited funds, so why should it be an issue if one party deposits 0 ?

okay so if that the case then I am not sure what is going on. We need to debug this issue. this could be more serious than I think

How to recreate

Pass one of the deposit as 0 and initiator amount very less then try closing the channel!

hey I think it gets paid from the deposit fund. See this decoded transaction post channel close. It takes 20000000000000 as fee. If one of the peer balance left is 0 then whole fee gets deducted from the other peer. But if both as sufficient amount left then the fee gets distributed among both of them equally.

image

Ok, so a lot of stuff here, I will try covering those one by one.

Balances checks

The check @vishwas_hypermine is talking about is already there. At channel opening time there is a variable called channel_reserve docs. I see in the JS SDK it is called channelReserve. From the docs:

Name Type Description
channel_reserve integer the minimum amount both peers need to maintain

This is the minimum amount of tokens any participant must always have while the channel is alive. This is their stake in it and it is intended for them to wish to either continue using the channel or close it.

You had set that to 0 and then any of the participants having an initial balance of 0 is fine. If you had used a greater value for the channelReserve - the check would have passed and you would have had bad time opening the channel. You can see the open errors here. Hint: in case of insufficant amount, you would see a Value too low error.

Initial balances

There is no issue if participants open the channel with some small amounts and then deposit more tokens in it. Also if you go to the coffeeshop - you don’t expect them to lock cash for your visit, I guess same logic could be applied with tokens in channels: the responder is likely to be the service provider and they could open the channel dedicating 0 tokens if that’s what both parties agree upon. So from practicality point of view - I don’t see why we should impose any further restrictions here (bearing in mind the channelReserve described above).

Close mutual transaction fees

Usually fees are payed by whoever posts the transaction (called origin). The channel_close_mutual_tx is somewhat special in that regard - since it is a subject of mutual agreement and both participants are expected to be equally benefiting from it - it is the channel that actually pays the fee (and @nikitafuchs.chain is wrong, sorry). The flow is the following: participants had locked totalAmountX tokens in the channel. Once they reach agreement on the final distribution of them, let’s say: amountA, amountB and fee, the following must be true:

amountA + amountB + fee =< totalAmountX

If for some reason they decide they want to redistribute less tokens than they’ve locked - they can, the excess amount is stored in a special burn address (so the inflation is not impacted).
How participants reach to this point is a completely different matter. What the FSM does is it simply splits the fee between them equally. If the fee is an odd number, the initiator pays 1 aetto more than the responder. What is important here is that this fee is being payed by their off-chain (locked in the channel) balances. If someone does not have enough tokens to cover their share of the fee - the other participants pays the difference. I believe this is what surprised you.

I will validate what happens when participants try closing the channel with a higher fee than they have provided in the channel and will write a followup comment.

Docker logs

At docker start time, you can mount a volume so you can access node’s internal logs. It would be something along the lines -v <absolute path to your local dir>:/home/aeternity/node/log. Then you can access all the logs:

$ ls
aestratum.log  aeternity.log  aeternity_metrics.log  aeternity_mining.log  aeternity_pow_cuckoo.log  aeternity_sync.log  crash.log

Usually when asking for logs, we need either parts of the aeternity.log and maybe the whole crash.log (if not empty).

2 Likes

A follow back comment: I’ve traced the reported Internal error message. Indeed there was a small bug (actually - two of them). When the fee provided exceeds the amounts available to participants in the channel, now the API will return a better error :slight_smile:

Now fixed in PR. Thanks @vishwas_hypermine!

4 Likes