Proposal for Changes to Balance

In our last post Problems with Balance, we described problems with the way Balance is calculated due to the BFS calling pattern in Tezos. Balance does not take into account a contract’s expected Incoming funds from operations later in the operation queue than the currently executing operation, and it does not take into account Outgoing funds already promised by the currently executing contract in operations in the queue that have not yet been executed. Here, we will propose a solution to this problem along with the minimum changes to the Tezos architecture the solution requires.

Solution

  1. Each contract will get a new storage variable: Outgoing. This does not require changes to Tezos architecture, just changes to the way Contracts are written. Tezos will maintain a global map Incoming : Contract –> Tez as it does Balance (this requires changes to Tezos architecture).

  2. Everytime a contract adds a transfer operation to its operation queue, it will also add the amount transferred in that operation to its storage variable Outgoing.

  3. Suppose Contract A invokes Contract B m times and each for invocation i of Contract B, B generates n transactions ti1, …, tin (where operation tij transfers A(tij) to T(tij)). Then, Tezos will make the following changes to how these n*m transactions are executed.

    1. Before any of these n*m transactions are executed, for all i,j Tezos will execute II(tij) (or Increase Incoming) which will add A (tij) to Incoming(T(tij)).
    2. For all i,j, for a given tij Tezos will generate another operation DI(tij) (or Decrease Incoming). DI(tij) will subtract A (tij) from Incoming(T(tij)). DI(tij) will execute immediately after tij executes.
    3. For all i,j, for a given tij Tezos will generate another operation DO(tij) (or Decrease Outcoming). DO(tij) is a self call that will subtract A(tij) from its own Outgoing storage variable. DO(tij) will execute immediately after DI(ij) executes.

    NOTE: For simplicity, points 1 and 2 in the list above are written to look like we are adding new operations to the operation queue. In reality these ‘operations’ just indicate a change in the way Tezos processes operation queues. Point 3 in the above list is indeed a new operation added to the operation list that could be implemented by contracts without changes to the tezos architecture. However, since 1 and 2 require changes to Tezos code, we suggest that point 3 is implemented by Tezos as well.

  4. Each contract can now get a new storage variable EffectiveBalance := Balance + Incoming - *Outgoing - Transferred (where we derefence a pointer to Outgoing so that changes to it in that contract’s code will be reflected in EffectiveBalance. Transferred refers to what is currently returned by AMOUNT opcode and is subtracted from calculation to correct for double counting of Transferred in Balance and Incoming.

Required Changes to Tezos Architecture

  1. Creation and maintenance of external map Incoming : Contract –> Tez, similar to existing one Balance. NOTE: In contrast to Incoming, a given contract’s Outcoming balance can be maintained as a storage variable in that contract, and does not require changes to Tezos architecture. However, that contract cannot know the amount being sent to it by another contract and we cannot rely on/trust external callers to accurately report the total amount they are sending to another contract across all operations. Therefore, Incoming must be maintained by Tezos.
  2. A new Opcode INCOMING which returns the calling contract’s expected incoming funds at time of execution.
  3. Changes to the Tezos scheduler that implement the solution described in point 3 of the above section.