WEP 9: Accept transactions with failed script result

Author Andrey Andreev <aandreev@wavesplatform.com >
Last update 2020-02-21

Abstract

We propose to accept blockchain transactions with failed script result.

All transactions with an authorized sender will be stored in blockchain, regardless of whether the transaction involves any change in the blockchain state.

The sender is considered authorized if the signature is correct for a regular account, or if the smart account/verifier script returns TRUE.

In this case, the transaction will be saved in the blockchain, and the sender account will be charged a fee.

If any of the remaining scripts (dApp script, participating asset scripts) returns error, the transaction will not cause any changes in the account data and account balance, except for the fee withdrawal.

Motivation and Purposes

At the moment, only the transactions with successful script execution result get into Waves blockchain. Users can send as many failed transactions as they want without any financial losses. To validate these transactions, the miners use resources without getting any profit. A large number of failed transactions reduces the speed at which valid transactions hit the block.

We find this situation unfair and propose to accept transactions with failed script result by debiting the fee from the sender of the transaction. This functionality will allow to compensate for the expenses of processing invalid transactions to the miners.

Specification

Transaction Validation

Validation when adding a transaction to a microblock
How it works now

  1. Checking transaction timestemp
  2. Checking the transaction version (all functionality supporting this version is activated)
  3. Checking transaction proofs (or checking the account script if the sender is a smart account)
  4. Checking the asset scripts attached as payment (if it is smart-asset)
  5. Checking whether the senderā€™s balance contains the asset used as fee and payment
  6. Checking for the required minimum fee and the attached payment to cover the transaction (checking the sponsorā€™s balance if the sponsorā€™s asset is used)
  7. Formation of State changes is better as a result of transaction execution
    7.1. If it is Invokescript transaction, the called script dApp is executed when the state changes are generated.
    7.2. All actions* are identified.
    7.3. Check of smart-asset scripts in actions is performed.
    7.4. The senderā€™s balance is checked to cover the transaction fee for all actions.
  8. Execution of transaction

How will it work

  1. Checking transaction timestemp
  2. Checking the transaction version (all functionality supporting this version is activated)
  3. Checking whether the senderā€™s balance contains the asset used as fee and payment
  4. Checking for the required minimum fee and the attached payment to cover the transaction (checking the sponsorā€™s balance if the sponsorā€™s asset is used)
  5. Checking transaction proofs (or checking the account script if it is a smart-account)
  6. Formation of State changes is better as a result of transaction execution
    6.1. If it is Invokescript transaction, the called script dApp is executed when the state changes are generated.
    6.2. All actions* are identified.
    6.3. Calculating the number of actions using the smart-asset and determining the amount of additional fee for script execution.
    6.4. The senderā€™s balance is checked to cover the transaction fee for all actions.
    6.5. Checking the asset scripts attached as payment (if they are smart-asset)
    6.6. Check of smart-asset scripts in actions is performed.
  7. Execution of transaction

What changed
Š”heck sender balance before the scripts are executed;
To authorize the sender of the transaction, the smart account script is executed first;
Before checking the action scripts resulting from the Invokescript transaction, the senderā€™s balance is checked in order to cover the additional fee for all actions* .

Actions * - are objects that make a change in a state as a result of executing an Invokescript transaction. List: ScriptTransfer; BinaryEntry; BooleanEntry; IntegerEntry; StringEntry; Issue; Reissue; Burn.

Rules for accepting invalid transactions at blockchain

If the sender is authorized (by account signature or script/verifier) and the result of smart-asset or dApp script execution is failed (script result " throw ") , transaction gets ā€œfailedā€ status and is saved in block.

If the transaction is failed for some other reason, due to the expiration of timestamp or verification of the smart account, then such transaction is not saved in the block. (Failure of a transaction at any of the stages 1-5 in the ā€œTransaction Validationā€ section does not result in saving transaction in a blockchain)

In case the fee size of a transaction is not enough to cover all actions defined during the script execution, it also assigns the transaction the ā€œfailedā€ status. Extra fee is charged for ScriptTransfer, Reissue, Burn smart-asset and Issue non-NFT asset.

Failed transactions are placed in blocks along with valid transactions. These txs do not change the state (the payments attached to the transaction remain in the senderā€™s account) but the sender of a failed transaction is charged the fee specified in the transaction. When using sponsorā€™s asset as fee for transaction, attached asset is transferred from the senderā€™s account to the sponsorā€™s account, and the sponsor pays a fee to Waves.

Withdrawal of Invoke script transaction fee from the funds received as a result of the script call execution

At the moment a user can send the Invoke Script Transaction from an account that does not have enough assets to pay the transaction fee. This is possible only if, as a result of the script execution, the sender receives enough assets from dApp to pay the transaction fee.

If the sender does not receive any money from dApp when calling the script, the transaction is considered invalid and doesnā€™t get into the blockchain. If the script execution result in the transfer of funds from dApp to the sender, the fee for the transaction was taken from the funds transferred to the sender.

After activation of this functionality, the above feature will not be available, because the transaction validation procedure will change.

Matcher fee from orders in Exchange transaction

Currently, matcher has the ability to create exchange transactions even if one of the ordersā€™ senders does not have enough funds in their account to cover the Matcher fee. This option is available when the orderā€™s sender gets the asset specified as matcher fee as a result of the transaction, so matcher can withhold its fee.

After the activation of this feature, the Exchange transaction will fail with an order that specifies Matcherā€™s fee which is not enough on the userā€™s balance to cover the specified fee.

Also, when validating an Exchange transaction with orders of versions 1 and 2, if the order matches partially, the maximum Matcher fee will be validated with the user specified in the order, without validating for a proportional withdrawal of the fee.

REST API

After activation of this functionality the REST API GET /transactions/info/{id} method together with transaction data must return the ā€œstatusā€ field: string (ā€œconfirmedā€ for valid transactions and ā€œfailedā€ for invalid transactions).

RIDE

The functions listed below should return data only for valid transactions. Unit should be returned for invalid transactions:

  • transactionHeightById(ByteVector): Int|Unit
  • transferTransactionById(ByteVector): TransferTransaction|Unit
  • transactionById(ByteVector): TransferTransaction|Unit (in Ride V2)

Reducing the maximum complexity of the account script and @Verifier

Since errors in the execution of the account/verifier script do not lead to the debiting of fee in favour of the network, it is proposed to reduce the maximum complexity of smart account/verifier scripts.

Presumably, up to 1000. To be determined as a result of the study.
Maximal dApp complexity will not be reduced.

Recommendations on sending transactions after functionality activation

In connection with the introduction of this functionality, we recommend users using the REST API POST /debug/validate method in order to check the validity of the transaction before sending Invoke script transaction or other transaction interacting with the smart-asset.

3 Likes

As someone that already use the ā€œfeatureā€ allowing to whitelist users and cover fee for them in my mainnet dapp, im not really fan of removing this possibility of course even though i understand the reasons but thats also something that was going to really make a difference in shutting down a big barrer to adoption, regular users would not have to get through the hassle of crypto aquisition to use a dapp.
Any possible alternative considered for this part?

Hi!
You can try the following idea.
You allow to invoke some function from behalf of your dApp in case you provide signature of the users account.
So your dApp will be the sender of the transaction, therefore the dApp will be charged for fee. At the same time user must sign this transaction in order @validator pass it.

At the example below you can also pass some ā€˜promo codeā€™ to the function which will check it. In the example itā€™s simple check, but it can be more sophisticated: you provide promocode, and check if itā€™s hash is present in the dAppā€™s state and not used yet.

https://ide.wavesplatform.com/s/5e5049005a0a16002917aacb

1 Like