Skip to content

Commit

Permalink
Update CAP-46-07 with the refundable->resource fee semantics changes. (
Browse files Browse the repository at this point in the history
…#1413)

* Update CAP-46-07 with the refundable->resource fee semantics changes.

Also did a passing-by update for ledger-wide IO limits.
  • Loading branch information
dmkozh authored Oct 24, 2023
1 parent 1abf481 commit 6d99ff0
Showing 1 changed file with 17 additions and 8 deletions.
25 changes: 17 additions & 8 deletions core/cap-0046-07.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ struct SorobanTransactionData
{
ExtensionPoint ext;
SorobanResources resources;
// Portion of transaction `fee` allocated to refundable fees.
int64 refundableFee;
// Portion of transaction `fee` allocated to resource fees.
int64 resourceFee;
};
```

Expand All @@ -164,7 +164,7 @@ struct SorobanTransactionData
#### Fee model overview

The approach taken in this proposal is to decompose the total transaction fee into the following additive components:
* `resourcesFee` - the fee for 'competitive' network resources (defined below) and non-refundable resources, based on the values *declared* in transaction and network-defined fee rates.
* `competitiveResourcesFee` - the fee for 'competitive' network resources (defined below) and non-refundable resources, based on the values *declared* in transaction and network-defined fee rates.
* `refundableResourcesFee` - the maximum fee for resources that don't need to be strictly restricted per ledger and thus are charged based on the actual usage.
* `inclusionFeeBid` - this is the "social value" part of the fee, it represents the intrinsic value that the submitter puts on that transaction.

Expand Down Expand Up @@ -201,17 +201,23 @@ All Soroban transactions must have `ext.sorobanData()` extension present and pop

Note, that `Historical_flat_fee` is a 'competitive' resource, but it's constant for any transaction execution result and thus is a part of non-refundable fee (as its refund is always 0).

`refundableFee` corresponds to the `refundableResourcesFee` component.
`resourceFee` corresponds to the sum of `competetiveResourcesFee` and `refundableResourcesFee` components.

The rules for limits and fee computation per-resource are specified in dedicated sections below.

At validation time total transaction fee (`tx.fee`) has to cover the fee components based only on the values declared in transaction:

`tx.fee = resourceFee(tx) + sorobanData.refundableFee + inclusionFeeBid`
`tx.fee = sorobanData.resourceFee + inclusionFeeBid`

Minimum valid `inclusionFeeBid` value is 100 stroops, thus the following condition has to be true:

`tx.fee >= resourceFee(tx) + sorobanData.refundableFee + 100`
`tx.fee >= sorobanData.resourceFee + 100`

`sorobanData.resourceFee` value has to cover the 'competetive' resource fee computed based on the declared resource values specified in `sorobanData` and transaction envelope size:

`sorobanData.resourceFee >= resourceFee(tx)`

The remaining value of `sorobanData.resourceFee - resourceFee(tx)` is considered to be a refundable part of the resource fee and has to cover the refundable resources consumed at apply time.

Similarly to 'classic' transactions, source account must be able to pay for the total fee (`tx.fee`) for the transaction.

Expand All @@ -229,11 +235,11 @@ At the end of the transaction execution, compute the final refundable fee for su

`effectiveRefundableFee = Events_fee(emittedContractEventsSizeBytes) + Rent_fee`

where `emittedContractEventsSizeBytes` is the size of the emitted contract events and invocation return value, and `Rent_fee` is the fee for the rent bumps performed by the transaction (if any). If `emittedContractEventsSizeBytes > sorobanData.refundableFee`, the transaction fails.
where `emittedContractEventsSizeBytes` is the size of the emitted contract events and invocation return value, and `Rent_fee` is the fee for the rent bumps performed by the transaction (if any). If `effectiveRefundableFee > sorobanData.resourceFee - resourceFee(tx)` (i.e. if actual required refundable fee is greater than the `refundableResourcesFee` component defined above), the transaction fails.

In case if transaction fails `effectiveRefundableFee` is set to `0`.

After executing the transaction, the refund amount is computed as `sorobanData.refundableFee - effectiveRefundableFee` and refund that amount (when non-zero) to the transaction source account. The ledger modification due to refund is reflected under `txChangesAfter` in the meta.
After executing the transaction, the refund amount is computed as `sorobanData.resourceFee - resourceFee(tx) - effectiveRefundableFee`. Protocol refunds that amount (when non-zero) to the transaction source account. The ledger modification due to refund is reflected under `txChangesAfter` in the meta.

Note, that refund happens for the failed transactions as well.

Expand Down Expand Up @@ -300,6 +306,9 @@ Validity constraints:
* `resources.writeBytes <= txMaxWriteBytes`.
* ledger wide (`GeneralizedTransactionSet`)
* `sum(length(resources.footprint.readOnly) + length(resources.footprint.readWrite)) <= ledgerMaxReadLedgerEntries`.
* `sum(length(resources.footprint.readWrite)) <= ledgerMaxWriteLedgerEntries`.
* `sum(resources.readBytes) <= ledgerMaxReadBytes`.
* `sum(resources.writeBytes) <= ledgerMaxWriteBytes`.

Apply-time enforcement:

Expand Down

0 comments on commit 6d99ff0

Please sign in to comment.