You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The current design of messageQueue only allows one chain of async messages to be stored. However on TON, it is sometimes useful to test how two different chains of async messages interact with a contract at the same time, for example in order to prevent MITM attack.
However this is just not possible with the current codebase because the current design only stores one chain of async messages.
So something like this will result in an unexpected result:
constA=blockchain.treasury(`A`)constB=blockchain.treasury(`B`)constC=blockchain.openContract(...)constbody_0= ...;constbody_1= ...;constmessages_0=awaitblockchain.sendMessageIter(internal({from: A.address,to: C.address,value: gas,body: body_0,}),);// There are outMessages, stillconstresult=awaitexecuteTill(messages_0,{success: true});// Want to test MITM flow, so we send another message before outMessages from the messages_0 are processedconstmessages_1=awaitblockchain.sendMessageIter(internal({from: B.address,to: C.address,value: gas,body: body_0,}),);// Exhaust the iterator (process all messages from messages_1)forawait(consttxofmessages_1){// do nothing}// Can't process outMessages from messages_0 anymore because `messageQueue` is replaced already. This will throw an error because there are no remaining messages left.constresult=awaitexecuteTill(messages_0,{success: true});
Describe the solution you'd like
There's a hacky solution that can be used by anyone now, which is to temporarily store the messageQueue yourself before you invoke another sendMessageIter:
constmessages_0=awaitblockchain.sendMessageIter(...)constpending_messages_0=// @ts-ignore: messageQueue is a protected propertyblockchain.messageQueue;// @ts-ignore: messageQueue is a protected propertyblockchain.messageQueue=[];constmessages_1=awaitblockchain.sendMessageIter(...)forawait(consttxofmessages_1){// do nothing}// Recover messages_0blockchain.messageQueue=pending_messages_0;// This will now workawaitexecuteTill(messages_0, ...)
...
But first of all, messageQueue is a protected property, so it requires using ts-ignore. Second of all, it is just very hacky.
I suggest that we maintain a map of PendingMessage[]: i.e. { [id: SomeUniqueId]: PendingMessage[] } so that any messageQueues can readily be accessed no matter how many different messageQueues there are.
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem? Please describe.
Once you send off a message using
blockchain.sendMessageIter
,messageQueue
will be populated with the nextPendingMessage
:sandbox/src/blockchain/Blockchain.ts
Line 161 in a6e62b4
sandbox/src/blockchain/Blockchain.ts
Line 312 in a6e62b4
The current design of messageQueue only allows one chain of async messages to be stored. However on TON, it is sometimes useful to test how two different chains of async messages interact with a contract at the same time, for example in order to prevent MITM attack.
However this is just not possible with the current codebase because the current design only stores one chain of async messages.
So something like this will result in an unexpected result:
Describe the solution you'd like
There's a hacky solution that can be used by anyone now, which is to temporarily store the
messageQueue
yourself before you invoke anothersendMessageIter
:But first of all,
messageQueue
is a protected property, so it requires usingts-ignore
. Second of all, it is just very hacky.I suggest that we maintain a map of
PendingMessage[]
: i.e.{ [id: SomeUniqueId]: PendingMessage[] }
so that anymessageQueue
s can readily be accessed no matter how many differentmessageQueue
s there are.The text was updated successfully, but these errors were encountered: