diff --git a/core/cap-0046-07.md b/core/cap-0046-07.md index 28798f52e..e0abfa06f 100644 --- a/core/cap-0046-07.md +++ b/core/cap-0046-07.md @@ -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; }; ``` @@ -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. @@ -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. @@ -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. @@ -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: