@@ -117,7 +117,7 @@ use frame_support::{
117
117
weights:: Weight ,
118
118
BoundedVec , RuntimeDebugNoBound , WeakBoundedVec ,
119
119
} ;
120
- use frame_system:: { ensure_signed, pallet_prelude:: OriginFor , Pallet as System } ;
120
+ use frame_system:: { ensure_signed, pallet_prelude:: OriginFor , EventRecord , Pallet as System } ;
121
121
use pallet_contracts_primitives:: {
122
122
Code , CodeUploadResult , CodeUploadReturnValue , ContractAccessError , ContractExecResult ,
123
123
ContractInstantiateResult , ExecReturnValue , GetStorageResult , InstantiateReturnValue ,
@@ -148,6 +148,8 @@ type CodeVec<T> = BoundedVec<u8, <T as Config>::MaxCodeLen>;
148
148
type RelaxedCodeVec < T > = WeakBoundedVec < u8 , <T as Config >:: MaxCodeLen > ;
149
149
type AccountIdLookupOf < T > = <<T as frame_system:: Config >:: Lookup as StaticLookup >:: Source ;
150
150
type DebugBufferVec < T > = BoundedVec < u8 , <T as Config >:: MaxDebugBufferLen > ;
151
+ type EventRecordOf < T > =
152
+ EventRecord < <T as frame_system:: Config >:: RuntimeEvent , <T as frame_system:: Config >:: Hash > ;
151
153
152
154
/// The old weight type.
153
155
///
@@ -971,6 +973,35 @@ struct InstantiateInput<T: Config> {
971
973
salt : Vec < u8 > ,
972
974
}
973
975
976
+ /// Determines whether events should be collected during execution.
977
+ #[ derive( PartialEq ) ]
978
+ pub enum CollectEvents {
979
+ /// Collect events.
980
+ ///
981
+ /// # Note
982
+ ///
983
+ /// Events should only be collected when called off-chain, as this would otherwise
984
+ /// collect all the Events emitted in the block so far and put them into the PoV.
985
+ ///
986
+ /// **Never** use this mode for on-chain execution.
987
+ UnsafeCollect ,
988
+ /// Skip event collection.
989
+ Skip ,
990
+ }
991
+
992
+ /// Determines whether debug messages will be collected.
993
+ #[ derive( PartialEq ) ]
994
+ pub enum DebugInfo {
995
+ /// Collect debug messages.
996
+ /// # Note
997
+ ///
998
+ /// This should only ever be set to `UnsafeDebug` when executing as an RPC because
999
+ /// it adds allocations and could be abused to drive the runtime into an OOM panic.
1000
+ UnsafeDebug ,
1001
+ /// Skip collection of debug messages.
1002
+ Skip ,
1003
+ }
1004
+
974
1005
/// Return type of private helper functions.
975
1006
struct InternalOutput < T : Config , O > {
976
1007
/// The gas meter that was used to execute the call.
@@ -1187,22 +1218,27 @@ impl<T: Config> Pallet<T> {
1187
1218
///
1188
1219
/// # Note
1189
1220
///
1190
- /// `debug` should only ever be set to `true` when executing as an RPC because
1191
- /// it adds allocations and could be abused to drive the runtime into an OOM panic.
1192
- /// If set to `true` it returns additional human readable debugging information.
1221
+ /// If `debug` is set to `DebugInfo::UnsafeDebug` it returns additional human readable debugging
1222
+ /// information.
1193
1223
///
1194
- /// It returns the execution result and the amount of used weight.
1224
+ /// If `collect_events` is set to `CollectEvents::UnsafeCollect` it collects all the Events
1225
+ /// emitted in the block so far and the ones emitted during the execution of this contract.
1195
1226
pub fn bare_call (
1196
1227
origin : T :: AccountId ,
1197
1228
dest : T :: AccountId ,
1198
1229
value : BalanceOf < T > ,
1199
1230
gas_limit : Weight ,
1200
1231
storage_deposit_limit : Option < BalanceOf < T > > ,
1201
1232
data : Vec < u8 > ,
1202
- debug : bool ,
1233
+ debug : DebugInfo ,
1234
+ collect_events : CollectEvents ,
1203
1235
determinism : Determinism ,
1204
- ) -> ContractExecResult < BalanceOf < T > > {
1205
- let mut debug_message = if debug { Some ( DebugBufferVec :: < T > :: default ( ) ) } else { None } ;
1236
+ ) -> ContractExecResult < BalanceOf < T > , EventRecordOf < T > > {
1237
+ let mut debug_message = if matches ! ( debug, DebugInfo :: UnsafeDebug ) {
1238
+ Some ( DebugBufferVec :: < T > :: default ( ) )
1239
+ } else {
1240
+ None
1241
+ } ;
1206
1242
let origin = Origin :: from_account_id ( origin) ;
1207
1243
let common = CommonInput {
1208
1244
origin,
@@ -1213,12 +1249,19 @@ impl<T: Config> Pallet<T> {
1213
1249
debug_message : debug_message. as_mut ( ) ,
1214
1250
} ;
1215
1251
let output = CallInput :: < T > { dest, determinism } . run_guarded ( common) ;
1252
+ let events = if matches ! ( collect_events, CollectEvents :: UnsafeCollect ) {
1253
+ Some ( System :: < T > :: read_events_no_consensus ( ) . map ( |e| * e) . collect ( ) )
1254
+ } else {
1255
+ None
1256
+ } ;
1257
+
1216
1258
ContractExecResult {
1217
1259
result : output. result . map_err ( |r| r. error ) ,
1218
1260
gas_consumed : output. gas_meter . gas_consumed ( ) ,
1219
1261
gas_required : output. gas_meter . gas_required ( ) ,
1220
1262
storage_deposit : output. storage_deposit ,
1221
1263
debug_message : debug_message. unwrap_or_default ( ) . to_vec ( ) ,
1264
+ events,
1222
1265
}
1223
1266
}
1224
1267
@@ -1231,9 +1274,11 @@ impl<T: Config> Pallet<T> {
1231
1274
///
1232
1275
/// # Note
1233
1276
///
1234
- /// `debug` should only ever be set to `true` when executing as an RPC because
1235
- /// it adds allocations and could be abused to drive the runtime into an OOM panic.
1236
- /// If set to `true` it returns additional human readable debugging information.
1277
+ /// If `debug` is set to `DebugInfo::UnsafeDebug` it returns additional human readable debugging
1278
+ /// information.
1279
+ ///
1280
+ /// If `collect_events` is set to `CollectEvents::UnsafeCollect` it collects all the Events
1281
+ /// emitted in the block so far.
1237
1282
pub fn bare_instantiate (
1238
1283
origin : T :: AccountId ,
1239
1284
value : BalanceOf < T > ,
@@ -1242,9 +1287,14 @@ impl<T: Config> Pallet<T> {
1242
1287
code : Code < CodeHash < T > > ,
1243
1288
data : Vec < u8 > ,
1244
1289
salt : Vec < u8 > ,
1245
- debug : bool ,
1246
- ) -> ContractInstantiateResult < T :: AccountId , BalanceOf < T > > {
1247
- let mut debug_message = if debug { Some ( DebugBufferVec :: < T > :: default ( ) ) } else { None } ;
1290
+ debug : DebugInfo ,
1291
+ collect_events : CollectEvents ,
1292
+ ) -> ContractInstantiateResult < T :: AccountId , BalanceOf < T > , EventRecordOf < T > > {
1293
+ let mut debug_message = if debug == DebugInfo :: UnsafeDebug {
1294
+ Some ( DebugBufferVec :: < T > :: default ( ) )
1295
+ } else {
1296
+ None
1297
+ } ;
1248
1298
let common = CommonInput {
1249
1299
origin : Origin :: from_account_id ( origin) ,
1250
1300
value,
@@ -1254,6 +1304,12 @@ impl<T: Config> Pallet<T> {
1254
1304
debug_message : debug_message. as_mut ( ) ,
1255
1305
} ;
1256
1306
let output = InstantiateInput :: < T > { code, salt } . run_guarded ( common) ;
1307
+ // collect events if CollectEvents is UnsafeCollect
1308
+ let events = if collect_events == CollectEvents :: UnsafeCollect {
1309
+ Some ( System :: < T > :: read_events_no_consensus ( ) . map ( |e| * e) . collect ( ) )
1310
+ } else {
1311
+ None
1312
+ } ;
1257
1313
ContractInstantiateResult {
1258
1314
result : output
1259
1315
. result
@@ -1263,6 +1319,7 @@ impl<T: Config> Pallet<T> {
1263
1319
gas_required : output. gas_meter . gas_required ( ) ,
1264
1320
storage_deposit : output. storage_deposit ,
1265
1321
debug_message : debug_message. unwrap_or_default ( ) . to_vec ( ) ,
1322
+ events,
1266
1323
}
1267
1324
}
1268
1325
@@ -1370,11 +1427,12 @@ impl<T: Config> Pallet<T> {
1370
1427
sp_api:: decl_runtime_apis! {
1371
1428
/// The API used to dry-run contract interactions.
1372
1429
#[ api_version( 2 ) ]
1373
- pub trait ContractsApi <AccountId , Balance , BlockNumber , Hash > where
1430
+ pub trait ContractsApi <AccountId , Balance , BlockNumber , Hash , EventRecord > where
1374
1431
AccountId : Codec ,
1375
1432
Balance : Codec ,
1376
1433
BlockNumber : Codec ,
1377
1434
Hash : Codec ,
1435
+ EventRecord : Codec ,
1378
1436
{
1379
1437
/// Perform a call from a specified account to a given contract.
1380
1438
///
@@ -1386,7 +1444,7 @@ sp_api::decl_runtime_apis! {
1386
1444
gas_limit: Option <Weight >,
1387
1445
storage_deposit_limit: Option <Balance >,
1388
1446
input_data: Vec <u8 >,
1389
- ) -> ContractExecResult <Balance >;
1447
+ ) -> ContractExecResult <Balance , EventRecord >;
1390
1448
1391
1449
/// Instantiate a new contract.
1392
1450
///
@@ -1399,8 +1457,7 @@ sp_api::decl_runtime_apis! {
1399
1457
code: Code <Hash >,
1400
1458
data: Vec <u8 >,
1401
1459
salt: Vec <u8 >,
1402
- ) -> ContractInstantiateResult <AccountId , Balance >;
1403
-
1460
+ ) -> ContractInstantiateResult <AccountId , Balance , EventRecord >;
1404
1461
1405
1462
/// Upload new code without instantiating a contract from it.
1406
1463
///
0 commit comments