@@ -322,53 +322,62 @@ where
322
322
let caller = self . self_account . clone ( ) ;
323
323
let dest = Contracts :: < T > :: contract_address ( & caller, code_hash, salt) ;
324
324
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) ;
329
328
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 ( ) ) ) ;
367
372
368
- // Deposit an instantiation event.
369
- deposit_event :: < T > ( vec ! [ ] , RawEvent :: Instantiated ( caller . clone ( ) , dest . clone ( ) ) ) ;
373
+ Ok ( output )
374
+ } ) ;
370
375
371
- Ok ( output)
376
+ use frame_support:: storage:: TransactionOutcome :: * ;
377
+ match output {
378
+ Ok ( _) => Commit ( output) ,
379
+ Err ( _) => Rollback ( output) ,
380
+ }
372
381
} ) ?;
373
382
374
383
Ok ( ( dest, output) )
@@ -908,7 +917,7 @@ mod tests {
908
917
let mut ctx = ExecutionContext :: top_level ( origin. clone ( ) , & cfg, & vm, & loader) ;
909
918
place_contract ( & BOB , return_ch) ;
910
919
set_balance ( & origin, 100 ) ;
911
- set_balance ( & dest, 0 ) ;
920
+ let balance = get_balance ( & dest) ;
912
921
913
922
let output = ctx. call (
914
923
dest. clone ( ) ,
@@ -919,7 +928,9 @@ mod tests {
919
928
920
929
assert ! ( !output. is_success( ) ) ;
921
930
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) ;
923
934
} ) ;
924
935
}
925
936
@@ -1057,10 +1068,10 @@ mod tests {
1057
1068
let cfg = ConfigCache :: preload ( ) ;
1058
1069
let mut ctx = ExecutionContext :: top_level ( ALICE , & cfg, & vm, & loader) ;
1059
1070
1060
- set_balance ( & ALICE , 100 ) ;
1071
+ set_balance ( & ALICE , cfg . subsistence_threshold ( ) * 10 ) ;
1061
1072
1062
1073
let result = ctx. instantiate (
1063
- cfg. subsistence_threshold ( ) ,
1074
+ cfg. subsistence_threshold ( ) * 3 ,
1064
1075
& mut GasMeter :: < Test > :: new ( GAS_LIMIT ) ,
1065
1076
& input_data_ch,
1066
1077
vec ! [ 1 , 2 , 3 , 4 ] ,
@@ -1307,7 +1318,7 @@ mod tests {
1307
1318
// Instantiate a contract and save it's address in `instantiated_contract_address`.
1308
1319
let ( address, output) = ctx. ext . instantiate (
1309
1320
& dummy_ch,
1310
- ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) ,
1321
+ ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) * 3 ,
1311
1322
ctx. gas_meter ,
1312
1323
vec ! [ ] ,
1313
1324
& [ 48 , 49 , 50 ] ,
@@ -1321,8 +1332,7 @@ mod tests {
1321
1332
ExtBuilder :: default ( ) . existential_deposit ( 15 ) . build ( ) . execute_with ( || {
1322
1333
let cfg = ConfigCache :: preload ( ) ;
1323
1334
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 ) ;
1326
1336
place_contract ( & BOB , instantiator_ch) ;
1327
1337
1328
1338
assert_matches ! (
@@ -1431,19 +1441,20 @@ mod tests {
1431
1441
let vm = MockVm :: new ( ) ;
1432
1442
let mut loader = MockLoader :: empty ( ) ;
1433
1443
let rent_allowance_ch = loader. insert ( |ctx| {
1444
+ let allowance = ConfigCache :: < Test > :: subsistence_threshold_uncached ( ) * 3 ;
1434
1445
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 ) ;
1437
1448
exec_success ( )
1438
1449
} ) ;
1439
1450
1440
1451
ExtBuilder :: default ( ) . build ( ) . execute_with ( || {
1441
1452
let cfg = ConfigCache :: preload ( ) ;
1442
1453
let mut ctx = ExecutionContext :: top_level ( ALICE , & cfg, & vm, & loader) ;
1443
- set_balance ( & ALICE , 100 ) ;
1454
+ set_balance ( & ALICE , cfg . subsistence_threshold ( ) * 10 ) ;
1444
1455
1445
1456
let result = ctx. instantiate (
1446
- cfg. subsistence_threshold ( ) ,
1457
+ cfg. subsistence_threshold ( ) * 5 ,
1447
1458
& mut GasMeter :: < Test > :: new ( GAS_LIMIT ) ,
1448
1459
& rent_allowance_ch,
1449
1460
vec ! [ ] ,
0 commit comments