-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
refactor: Billing refactor #992
refactor: Billing refactor #992
Conversation
Looks like this PR is quite big and contains many things. Is it possible to split the PR into smaller things? Smaller PR will make it easier to test and review. |
Hi @iwanbk
I believe keeping the PR as a single unit will ensure a smoother review and testing process. I am, of course, open to any specific suggestions you might have to improve the PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Partial review
substrate-node/pallets/pallet-smart-contract/src/migrations/v9.rs
Outdated
Show resolved
Hide resolved
…ub.com/threefoldtech/tfchain into development-contracts-billing-refactor
I added the comment for clarity. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I went deeper on reviewing the v12 migration.
It is already good, I just made some comments for improvement.
Tell me what you think.
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
…ub.com/threefoldtech/tfchain into development-contracts-billing-refactor
One last change I prefer to have a None returned and fail gracefully, rather than having a default value. |
Indeed, if we don't make a specific usage of a default value it is more convenient to use |
substrate-node/pallets/pallet-smart-contract/src/migrations/v12.rs
Outdated
Show resolved
Hide resolved
@renauter Thank you so much for reviewing! It was really helpful. |
@sameh-farouk Thank you for your tremendous work!! This refactoring was a very hard task 👏🏻👏🏻👏🏻 |
// Burn 35%, to not have any imbalance in the system, subtract all previously send amounts with the initial | ||
let amount_to_burn = | ||
(Perbill::from_percent(50) * amount) - foundation_share - staking_pool_share; | ||
Self::transfer_reserved(&src_twin.account_id, &dst_twin.account_id, farmer_share)?; | ||
|
||
let to_burn = T::Currency::withdraw( | ||
&twin.account_id, | ||
amount_to_burn, | ||
WithdrawReasons::FEE, | ||
ExistenceRequirement::KeepAlive, | ||
)?; | ||
(foundation_percent, foundation_share) | ||
} else { | ||
// Where no 3node utilized (Name contracts) | ||
// Calculate foundation share (90%) | ||
let foundation_percent = 90; | ||
// We calculate it by subtract all previously send amounts with the initial to avoid accumulating rounding errors. | ||
let foundation_share = standard_rewards.defensive_saturating_sub(staking_pool_share); | ||
|
||
(foundation_percent, foundation_share) | ||
}; | ||
// Transfer foundation share | ||
log::debug!( | ||
"Burning: {:?} from contract twin {:?}", | ||
amount_to_burn, | ||
&twin.account_id | ||
"Transferring: {:?} ({:}%) from twin {:?} to foundation account {:?}", | ||
foundation_share, | ||
foundation_percent, | ||
src_twin.id, | ||
pricing_policy.foundation_account, | ||
); | ||
T::Burn::on_unbalanced(to_burn); | ||
Self::transfer_reserved( | ||
&src_twin.account_id, | ||
&pricing_policy.foundation_account, | ||
foundation_share, | ||
)?; | ||
|
||
Self::deposit_event(Event::TokensBurned { | ||
contract_id: contract.contract_id, | ||
amount: amount_to_burn, | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Burning was removed here @xmonader
Description
This PR addresses several issues and introduces significant changes to the billing in the pallet-smart-contract module. Here are the key changes and the issues they resolve:
High-Level Changes:
Find below more details
Key Changes and Improvements:
Refactoring Billing Logic:
The billing logic has been refactored to improve the billing feature for smart contracts. This includes more precise tracking of contract payments, handling of overdrafts, and fund reservations.
Improved off-chain worker logic
Updated off-chain worker logic to handle billing more effectively.
is_next_block_author
function was removed and the verification is now happening at runtime, ensuring that transaction fees are reliably waived for validators and still preventing duplicate transactions. It also implements a guaranteed execution layer for OCWs by enabling redundancy.Benefits:
Additionally, the improved logging ensures that the off-chain worker function works correctly without silent failures.
Introduction of ContractPaymentState:
Introducing ContractPaymentState aligns with the need to track and manage contract payment states accurately, especially during grace periods and when handling overdue payments.
It fixes the issue where the amount tracked in the contract lock is incorrectly divergent from the lock on the user balance, leading to illiquidity issues when it's time to distribute rewards.
Improved Error Handling:
Enhanced error-handling mechanisms have been introduced to ensure that errors during billing are logged and appropriately managed, reducing the likelihood of contracts entering a dirty state.
Also, New error types were added
RewardDistributionError
andContractPaymentStateNotExists
.Enhanced Events:
New events have been added, ContractGracePeriodElapsed, ContractPaymentOverdrafted, and RewardDistributed, to provide better visibility into the billing and payment processes.
ContractPaymentOverdrawn
: This event is closely related to the ContractBilled event. Both events provide information about the amount due for the previous billing period. The ContractBilled event indicates that the due amount was successfully charged to the user's account. In contrast, the ContractPaymentOverdrawn event signifies that the due amount was not fully covered and has been added to the contract's overdraft. This distinction helps in accurately tracking the financial state of contracts.RewardDistributed
: This event signifies the successful distribution of rewards after the billing cycle, providing transparency and traceability for reward payouts.ContractGracePeriodElapsed
: This event is triggered when a contract has exceeded its grace period without sufficient funds, leading to its transition to a deleted state.Other Events changes:
Locked
: It have been replaced with Reserved event.TokenBurned
: The TokenBurned event is no longer emitted, reflecting the removal of TFT burning from TFChain.Unlocked
andTransfer
Events: Both the Unlocked and Transfer events have been replaced with theReserveRepatriated
event.Issues Addressed:
Issue #996
Issue #991:
Issue #990:
Reserves align better with handling common billing scenarios such as partial payments, fund releases, and transfers more straightforwardly and reliably.
Issue #979:
Issue #969 :
Issue #932 :
Issue #834:
Issue #994:
Overall, this PR enhances the billing capabilities of the pallet-smart-contract module, making it more robust and reliable.
TODO
Some reconsideration might be needed, such as:
Using the newer hold in the fungible trait instead of reserves in reservableCurrency, as the latter is marked for deprecation in future versions.Checklist: