diff --git a/substrate/node/runtime/src/lib.rs b/substrate/node/runtime/src/lib.rs index d0d603bb10d33f216169389e9b150f38abc1db24..69a19bf05e4fbd61382dd7247a9abdfd1ffc76c3 100644 --- a/substrate/node/runtime/src/lib.rs +++ b/substrate/node/runtime/src/lib.rs @@ -59,7 +59,7 @@ pub const VERSION: RuntimeVersion = RuntimeVersion { impl_name: create_runtime_str!("substrate-node"), authoring_version: 10, spec_version: 72, - impl_version: 72, + impl_version: 73, apis: RUNTIME_API_VERSIONS, }; diff --git a/substrate/srml/contract/src/rent.rs b/substrate/srml/contract/src/rent.rs index b914e41af3198c94e5d95adf62888f242e8bd001..5466e2553d90b2236102990374b391ebec4726f5 100644 --- a/substrate/srml/contract/src/rent.rs +++ b/substrate/srml/contract/src/rent.rs @@ -55,10 +55,12 @@ fn try_evict_or_and_pay_rent<T: Trait>( Some(ContractInfo::Alive(contract)) => contract, }; + let current_block_number = <system::Module<T>>::block_number(); + // How much block has passed since the last deduction for the contract. let blocks_passed = { // Calculate an effective block number, i.e. after adjusting for handicap. - let effective_block_number = <system::Module<T>>::block_number().saturating_sub(handicap); + let effective_block_number = current_block_number.saturating_sub(handicap); let n = effective_block_number.saturating_sub(contract.deduct_block); if n.is_zero() { // Rent has already been paid @@ -125,11 +127,13 @@ fn try_evict_or_and_pay_rent<T: Trait>( ); <ContractInfoOf<T>>::mutate(account, |contract| { - contract + let contract = contract .as_mut() .and_then(|c| c.as_alive_mut()) - .expect("Dead or inexistent account has been exempt above; qed") - .rent_allowance -= imbalance.peek(); // rent_allowance is not exceeded + .expect("Dead or inexistent account has been exempt above; qed"); + + contract.rent_allowance -= imbalance.peek(); // rent_allowance is not exceeded + contract.deduct_block = current_block_number; }) } diff --git a/substrate/srml/contract/src/tests.rs b/substrate/srml/contract/src/tests.rs index 2ce4f30503c386002dd6ca6b74f38c019a7bd14d..8065999d5ceca09568c6f1ce06955b08600efe00 100644 --- a/substrate/srml/contract/src/tests.rs +++ b/substrate/srml/contract/src/tests.rs @@ -718,7 +718,31 @@ fn deduct_blocks() { * 4; // blocks to rent let bob_contract = super::ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap(); assert_eq!(bob_contract.rent_allowance, 1_000 - rent); + assert_eq!(bob_contract.deduct_block, 5); assert_eq!(Balances::free_balance(BOB), 30_000 - rent); + + // Advance 7 blocks more + System::initialize(&12, &[0u8; 32].into(), &[0u8; 32].into()); + + // Trigger rent through call + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + // Check result + let rent_2 = (8 + 4 - 2) // storage size = size_offset + deploy_set_storage - deposit_offset + * 4 // rent byte price + * 7; // blocks to rent + let bob_contract = super::ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); + + // Second call on same block should have no effect on rent + assert_ok!(Contract::call(Origin::signed(ALICE), BOB, 0, 100_000, call::null())); + + let bob_contract = super::ContractInfoOf::<Test>::get(BOB).unwrap().get_alive().unwrap(); + assert_eq!(bob_contract.rent_allowance, 1_000 - rent - rent_2); + assert_eq!(bob_contract.deduct_block, 12); + assert_eq!(Balances::free_balance(BOB), 30_000 - rent - rent_2); } ); }