@@ -322,53 +322,62 @@ where
322322 let caller = self . self_account . clone ( ) ;
323323 let dest = Contracts :: < T > :: contract_address ( & caller, code_hash, salt) ;
324324
325- // TrieId has not been generated yet and storage is empty since contract is new.
326- //
327- // Generate it now.
328- let dest_trie_id = Storage :: < T > :: generate_trie_id ( & dest) ;
325+ let output = frame_support:: storage:: with_transaction ( || {
326+ // Generate the trie id in a new transaction to only increment the counter on success.
327+ let dest_trie_id = Storage :: < T > :: generate_trie_id ( & dest) ;
329328
330- let output = self . with_nested_context ( dest. clone ( ) , dest_trie_id, |nested| {
331- Storage :: < T > :: place_contract (
332- & dest,
333- nested
334- . self_trie_id
335- . clone ( )
336- . expect ( "the nested context always has to have self_trie_id" ) ,
337- code_hash. clone ( )
338- ) ?;
339-
340- // Send funds unconditionally here. If the `endowment` is below existential_deposit
341- // then error will be returned here.
342- transfer (
343- TransferCause :: Instantiate ,
344- transactor_kind,
345- & caller,
346- & dest,
347- endowment,
348- nested,
349- ) ?;
350-
351- let executable = nested. loader . load_init ( & code_hash)
352- . map_err ( |_| Error :: < T > :: CodeNotFound ) ?;
353- let output = nested. vm
354- . execute (
355- & executable,
356- nested. new_call_context ( caller. clone ( ) , endowment) ,
357- input_data,
358- gas_meter,
359- ) . map_err ( |e| ExecError { error : e. error , origin : ErrorOrigin :: Callee } ) ?;
360-
361- // We need each contract that exists to be above the subsistence threshold
362- // in order to keep up the guarantuee that we always leave a tombstone behind
363- // with the exception of a contract that called `seal_terminate`.
364- if T :: Currency :: total_balance ( & dest) < nested. config . subsistence_threshold ( ) {
365- Err ( Error :: < T > :: NewContractNotFunded ) ?
366- }
329+ let output = self . with_nested_context ( dest. clone ( ) , dest_trie_id, |nested| {
330+ Storage :: < T > :: place_contract (
331+ & dest,
332+ nested
333+ . self_trie_id
334+ . clone ( )
335+ . expect ( "the nested context always has to have self_trie_id" ) ,
336+ code_hash. clone ( )
337+ ) ?;
338+
339+ // Send funds unconditionally here. If the `endowment` is below existential_deposit
340+ // then error will be returned here.
341+ transfer (
342+ TransferCause :: Instantiate ,
343+ transactor_kind,
344+ & caller,
345+ & dest,
346+ endowment,
347+ nested,
348+ ) ?;
349+
350+ let executable = nested. loader . load_init ( & code_hash)
351+ . map_err ( |_| Error :: < T > :: CodeNotFound ) ?;
352+ let output = nested. vm
353+ . execute (
354+ & executable,
355+ nested. new_call_context ( caller. clone ( ) , endowment) ,
356+ input_data,
357+ gas_meter,
358+ ) . map_err ( |e| ExecError { error : e. error , origin : ErrorOrigin :: Callee } ) ?;
359+
360+
361+ // Collect the rent for the first block to prevent the creation of very large
362+ // contracts that never intended to pay for even one block.
363+ // This also makes sure that it is above the subsistence threshold
364+ // in order to keep up the guarantuee that we always leave a tombstone behind
365+ // with the exception of a contract that called `seal_terminate`.
366+ Rent :: < T > :: charge ( & dest) ?
367+ . and_then ( |c| c. get_alive ( ) )
368+ . ok_or_else ( || Error :: < T > :: NewContractNotFunded ) ?;
369+
370+ // Deposit an instantiation event.
371+ deposit_event :: < T > ( vec ! [ ] , RawEvent :: Instantiated ( caller. clone ( ) , dest. clone ( ) ) ) ;
367372
368- // Deposit an instantiation event.
369- deposit_event :: < T > ( vec ! [ ] , RawEvent :: Instantiated ( caller . clone ( ) , dest . clone ( ) ) ) ;
373+ Ok ( output )
374+ } ) ;
370375
371- Ok ( output)
376+ use frame_support:: storage:: TransactionOutcome :: * ;
377+ match output {
378+ Ok ( _) => Commit ( output) ,
379+ Err ( _) => Rollback ( output) ,
380+ }
372381 } ) ?;
373382
374383 Ok ( ( dest, output) )
@@ -908,7 +917,7 @@ mod tests {
908917 let mut ctx = ExecutionContext :: top_level ( origin. clone ( ) , & cfg, & vm, & loader) ;
909918 place_contract ( & BOB , return_ch) ;
910919 set_balance ( & origin, 100 ) ;
911- set_balance ( & dest, 0 ) ;
920+ let balance = get_balance ( & dest) ;
912921
913922 let output = ctx. call (
914923 dest. clone ( ) ,
@@ -919,7 +928,9 @@ mod tests {
919928
920929 assert ! ( !output. is_success( ) ) ;
921930 assert_eq ! ( get_balance( & origin) , 100 ) ;
922- assert_eq ! ( get_balance( & dest) , 0 ) ;
931+
932+ // the rent is still charged
933+ assert ! ( get_balance( & dest) < balance) ;
923934 } ) ;
924935 }
925936
@@ -1057,10 +1068,10 @@ mod tests {
10571068 let cfg = ConfigCache :: preload ( ) ;
10581069 let mut ctx = ExecutionContext :: top_level ( ALICE , & cfg, & vm, & loader) ;
10591070
1060- set_balance ( & ALICE , 100 ) ;
1071+ set_balance ( & ALICE , cfg . subsistence_threshold ( ) * 10 ) ;
10611072
10621073 let result = ctx. instantiate (
1063- cfg. subsistence_threshold ( ) ,
1074+ cfg. subsistence_threshold ( ) * 3 ,
10641075 & mut GasMeter :: < Test > :: new ( GAS_LIMIT ) ,
10651076 & input_data_ch,
10661077 vec ! [ 1 , 2 , 3 , 4 ] ,
@@ -1307,7 +1318,7 @@ mod tests {
13071318 // Instantiate a contract and save it's address in `instantiated_contract_address`.
13081319 let ( address, output) = ctx. ext . instantiate (
13091320 & dummy_ch,
1310- ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) ,
1321+ ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) * 3 ,
13111322 ctx. gas_meter ,
13121323 vec ! [ ] ,
13131324 & [ 48 , 49 , 50 ] ,
@@ -1321,8 +1332,7 @@ mod tests {
13211332 ExtBuilder :: default ( ) . existential_deposit ( 15 ) . build ( ) . execute_with ( || {
13221333 let cfg = ConfigCache :: preload ( ) ;
13231334 let mut ctx = ExecutionContext :: top_level ( ALICE , & cfg, & vm, & loader) ;
1324- set_balance ( & ALICE , 1000 ) ;
1325- set_balance ( & BOB , 100 ) ;
1335+ set_balance ( & ALICE , cfg. subsistence_threshold ( ) * 100 ) ;
13261336 place_contract ( & BOB , instantiator_ch) ;
13271337
13281338 assert_matches ! (
@@ -1431,19 +1441,20 @@ mod tests {
14311441 let vm = MockVm :: new ( ) ;
14321442 let mut loader = MockLoader :: empty ( ) ;
14331443 let rent_allowance_ch = loader. insert ( |ctx| {
1444+ let allowance = ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) * 3 ;
14341445 assert_eq ! ( ctx. ext. rent_allowance( ) , <BalanceOf <Test >>:: max_value( ) ) ;
1435- ctx. ext . set_rent_allowance ( 10 ) ;
1436- assert_eq ! ( ctx. ext. rent_allowance( ) , 10 ) ;
1446+ ctx. ext . set_rent_allowance ( allowance ) ;
1447+ assert_eq ! ( ctx. ext. rent_allowance( ) , allowance ) ;
14371448 exec_success ( )
14381449 } ) ;
14391450
14401451 ExtBuilder :: default ( ) . build ( ) . execute_with ( || {
14411452 let cfg = ConfigCache :: preload ( ) ;
14421453 let mut ctx = ExecutionContext :: top_level ( ALICE , & cfg, & vm, & loader) ;
1443- set_balance ( & ALICE , 100 ) ;
1454+ set_balance ( & ALICE , cfg . subsistence_threshold ( ) * 10 ) ;
14441455
14451456 let result = ctx. instantiate (
1446- cfg. subsistence_threshold ( ) ,
1457+ cfg. subsistence_threshold ( ) * 5 ,
14471458 & mut GasMeter :: < Test > :: new ( GAS_LIMIT ) ,
14481459 & rent_allowance_ch,
14491460 vec ! [ ] ,
0 commit comments