1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
//! This module implements traits for the contract interface.
//! This allows setting-up mock objects for testing individual
//! contract invocations.

#[cfg(not(feature = "std"))]
use crate::vec::Vec;
use crate::{
    types::{LogError, StateError},
    AccountSignatures, CallContractResult, CheckAccountSignatureResult, EntryRaw, ExchangeRates,
    HashKeccak256, HashSha2256, HashSha3256, Key, OccupiedEntryRaw, PublicKeyEcdsaSecp256k1,
    PublicKeyEd25519, QueryAccountBalanceResult, QueryAccountPublicKeysResult,
    QueryContractBalanceResult, ReadOnlyCallContractResult, SignatureEcdsaSecp256k1,
    SignatureEd25519, StateBuilder, TransferResult, UpgradeResult, VacantEntryRaw,
};
#[cfg(feature = "p7")]
use crate::{QueryContractModuleReferenceResult, QueryContractNameResult};
use concordium_contracts_common::*;

/// Objects which can access parameters to contracts.
///
/// This trait has a Read supertrait which means that structured parameters can
/// be directly deserialized by using `.get()` function from the `Get` trait.
///
/// The reuse of `Read` methods is the reason for the slightly strange choice of
/// methods of this trait.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`ExternParameter`](crate::types::ExternParameter) instead unless you
/// intend to use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasParameter: Read + Seek + HasSize {}

/// Objects which can access call responses from contract invocations.
///
/// This trait has a Read supertrait which means that structured call responses
/// can be directly deserialized by using `.get()` function from the `Get`
/// trait.
///
/// The reuse of `Read` methods is the reason for the slightly strange choice of
/// methods of this trait.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`CallResponse`](crate::types::CallResponse) instead unless you intend
/// to use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasCallResponse: Read {
    /// Get the size of the call response to the contract invocation.
    fn size(&self) -> u32;
}

/// Objects which can access chain metadata.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`ChainMetadata`] instead unless you intend to use
/// the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasChainMetadata {
    /// Get time in milliseconds at the beginning of this block.
    fn slot_time(&self) -> SlotTime;
    /// Get time in milliseconds at the beginning of this block.
    #[inline(always)]
    fn block_time(&self) -> Timestamp { self.slot_time() }
}

/// A type which has access to a policy of a credential.
/// Since policies can be large this is deliberately written in a relatively
/// low-level style to enable efficient traversal of all the attributes without
/// any allocations.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`Policy<AttributeCursor>`] instead unless you intend to use the
/// deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasPolicy: Sized {
    type Iterator: Iterator<Item = (AttributeTag, AttributeValue)>;
    /// Identity provider who signed the identity object the credential is
    /// derived from.
    fn identity_provider(&self) -> IdentityProvider;
    /// Beginning of the month in milliseconds since unix epoch when the
    /// credential was created.
    fn created_at(&self) -> Timestamp;
    /// Beginning of the month where the credential is no longer valid, in
    /// milliseconds since unix epoch.
    fn valid_to(&self) -> Timestamp;
    /// Get the next attribute, storing it in the provided buffer.
    /// The return value, if `Some`, is a pair of an attribute tag, and the
    /// length, `n` of the attribute value. In this case, the attribute
    /// value is written in the first `n` bytes of the provided buffer. The
    /// rest of the buffer is unchanged.
    ///
    /// The reason this function is added here, and we don't simply implement
    /// an Iterator for this type is that with the supplied buffer we can
    /// iterate through the elements more efficiently, without any allocations,
    /// the consumer being responsible for allocating the buffer.
    fn next_item(&mut self, buf: &mut [u8; 31]) -> Option<(AttributeTag, u8)>;
    /// Get an iterator over all the attributes of the policy.
    fn attributes(&self) -> Self::Iterator;
}

/// Common data accessible to both init and receive methods.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`InitContext`](crate::types::InitContext) or
/// [`ReceiveContext`](crate::types::ReceiveContext) instead unless you intend
/// to use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasCommonData {
    type PolicyType: HasPolicy;
    type MetadataType: HasChainMetadata;
    type ParamType: HasParameter + Read;
    type PolicyIteratorType: ExactSizeIterator<Item = Self::PolicyType>;
    /// Policies of the sender of the message.
    /// For init methods this is the would-be creator of the contract,
    /// for the receive this is the policies of the immediate sender.
    ///
    /// In the latter case, if the sender is an account then it is the policies
    /// of the account, if it is a contract then it is the policies of the
    /// creator of the contract.
    fn policies(&self) -> Self::PolicyIteratorType;
    /// Get the reference to chain metadata
    fn metadata(&self) -> &Self::MetadataType;
    /// Get the cursor to the parameter.
    fn parameter_cursor(&self) -> Self::ParamType;
}

/// Types which can act as init contexts.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`InitContext`](crate::types::InitContext) instead unless you intend to
/// use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasInitContext<Error: Default = ()>: HasCommonData {
    /// Data needed to open the context.
    type InitData;
    /// Open the init context for reading and accessing values.
    fn open(data: Self::InitData) -> Self;
    /// Who invoked this init call.
    fn init_origin(&self) -> AccountAddress;
}

/// Types which can act as receive contexts.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`ReceiveContext`](crate::types::ReceiveContext) instead unless you
/// intend to use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasReceiveContext<Error: Default = ()>: HasCommonData {
    type ReceiveData;

    /// Open the receive context for reading and accessing values.
    fn open(data: Self::ReceiveData) -> Self;
    /// Who is the account that initiated the top-level transaction this
    /// invocation is a part of.
    fn invoker(&self) -> AccountAddress;
    /// The address of the contract being invoked.
    fn self_address(&self) -> ContractAddress;
    /// The immediate sender of the message. In general different from the
    /// invoker.
    fn sender(&self) -> Address;
    /// Account which created the contract instance.
    fn owner(&self) -> AccountAddress;
    /// Get the name of the entrypoint that was named. In case a default
    /// entrypoint is invoked this can be different from the name of the
    /// entrypoint that is being executed.
    fn named_entrypoint(&self) -> OwnedEntrypointName;
}

/// A type that can serve as the contract state entry type.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`StateEntry`](crate::types::StateEntry) instead unless you intend to
/// use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasStateEntry
where
    Self: Read,
    Self: Write<Err = Self::Error>,
    Self: Seek<Err = Self::Error>, {
    type StateEntryData;
    type StateEntryKey;
    type Error: Default;

    /// Set the cursor to the beginning. Equivalent to
    /// `.seek(SeekFrom::Start(0))` but can be implemented more efficiently.
    fn move_to_start(&mut self);

    /// Get the current size of the entry.
    /// Returns an error if the entry does not exist.
    fn size(&self) -> Result<u32, Self::Error>;

    /// Truncate the entry to the given size. If the given size is more than the
    /// current size this operation does nothing. The new position is at
    /// most at the end of the stream.
    /// Returns an error if the entry does not exist.
    fn truncate(&mut self, new_size: u32) -> Result<(), Self::Error>;

    /// Make sure that the memory size is at least that many bytes in size.
    /// Returns `Ok` iff this was successful. The new bytes are initialized as
    /// 0.
    /// Returns an error if the entry does not exist.
    fn reserve(&mut self, len: u32) -> Result<(), Self::Error> {
        if self.size()? < len {
            self.resize(len)
        } else {
            Ok(())
        }
    }

    /// Get a reference to the entry's key.
    fn get_key(&self) -> &[u8];

    /// Resize the entry to the given size.
    /// Returns an error if the entry does not exist.
    fn resize(&mut self, new_size: u32) -> Result<(), Self::Error>;
}

/// Types which can serve as the contract state.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`StateApi`](crate::types::StateApi) instead unless you intend to use
/// the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasStateApi: Clone {
    type EntryType: HasStateEntry;
    type IterType: Iterator<Item = Self::EntryType>;

    /// Create a new entry in the state. If an entry with the given key already
    /// exists then it is reset to an empty entry. If the part of the tree
    /// where the key points to is locked due to an acquired iterator
    /// then no entry is created, and an error will be returned.
    fn create_entry(&mut self, key: &[u8]) -> Result<Self::EntryType, StateError>;

    /// Lookup an entry in the state.
    fn lookup_entry(&self, key: &[u8]) -> Option<Self::EntryType>;

    /// Like [`lookup_entry`](Self::lookup_entry) except that it consumes the
    /// key and returns an [`EntryRaw`] instead of an optional entry.
    ///
    /// For maximal flexibility the function is parametrized by the type of key
    /// with the intention that needless allocations are avoided for short
    /// keys and existing entries. The most common examples of keys will be [`Vec<u8>`](Vec) or fixed sized arrays [`[u8; N]`](https://doc.rust-lang.org/std/primitive.array.html).
    fn entry<K: AsRef<[u8]> + Into<Key>>(&mut self, key: K) -> EntryRaw<Self> {
        match self.lookup_entry(key.as_ref()) {
            Some(e) => EntryRaw::Occupied(OccupiedEntryRaw::new(e)),
            None => EntryRaw::Vacant(VacantEntryRaw::new(key.into(), self.clone())),
        }
    }

    /// Delete an entry.
    /// Returns an error if the entry did not exist, or if it is part of a
    /// locked subtree.
    fn delete_entry(&mut self, entry: Self::EntryType) -> Result<(), StateError>;

    /// Delete the entire subtree.
    /// Returns whether any values were deleted, or an error if the given prefix
    /// is part of a locked subtree.
    fn delete_prefix(&mut self, prefix: &[u8]) -> Result<bool, StateError>;

    /// Get an iterator over a map in the state.
    ///
    /// An iterator locks the subtree with the given prefix.
    /// Locking means that the structure of the tree cannot be altered, i.e.,
    /// that entries cannot be created or deleted. Altering the data inside
    /// an entry of a locked subtree is, however, allowed.
    ///
    /// Deleting iterators with
    /// [`delete_iterator`][HasStateApi::delete_iterator] is necessary to
    /// unlock the subtree. To unlock a subtree with prefix
    /// `p1`, all iterators with prefixes `p2`, where `p2` is a prefix of `p1`,
    /// must be deleted.
    ///
    /// Returns an error if the number of active iterators for the same prefix
    /// exceeds [u32::MAX].
    fn iterator(&self, prefix: &[u8]) -> Result<Self::IterType, StateError>;

    /// Delete an iterator.
    /// See the [`iterator`][HasStateApi::iterator] method for why this is
    /// necessary.
    fn delete_iterator(&mut self, iter: Self::IterType);

    /// Read and deserialize the state stored at the root of the state trie.
    /// If such a state does not exist, or cannot be deserialized into the
    /// provided type, then this returns an error.
    fn read_root<A: DeserialWithState<Self>>(&self) -> ParseResult<A> {
        A::deserial_with_state(self, &mut self.lookup_entry(&[]).ok_or(ParseError {})?)
    }

    /// Serialize and write the state at the root of the state trie. Dual to
    /// [`read_root`](Self::read_root).
    fn write_root<A: Serial>(&mut self, new_state: &A) {
        new_state.serial(&mut self.create_entry(&[]).unwrap_abort()).unwrap_abort()
    }
}

/// A type that can serve as the host, meaning that it supports interactions
/// with the chain, such as querying balance of the contract, accessing its
/// state, and invoking operations on other contracts and accounts.
///
/// The trait is parameterized by the `State` type. This is the type of the
/// contract state that the particular contract operates on.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`Host`](crate::types::Host) instead unless you intend to use
/// the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasHost<State>: Sized {
    /// The type of low-level state that is associated with the host.
    /// This provides access to low-level state operations.
    type StateApiType: HasStateApi;

    /// The type of return values this host provides. This is the raw return
    /// value. The intention is that it will be deserialized by the
    /// consumer, via the [Read] implementation.
    ///
    /// The Debug requirement exists so that consumers of this trait may use
    /// methods like [ExpectReport::expect_report].
    type ReturnValueType: HasCallResponse + crate::fmt::Debug;

    /// Perform a transfer to the given account if the contract has sufficient
    /// balance.
    fn invoke_transfer(&self, receiver: &AccountAddress, amount: Amount) -> TransferResult;

    /// Invoke a given method of a contract with the amount and parameter
    /// provided. If invocation succeeds then the return value is a pair of
    /// a boolean which indicates whether the state of the contract has changed
    /// or not, and a possible return value. The return value is present if and
    /// only if a V1 contract was invoked.
    fn invoke_contract_raw(
        &mut self,
        to: &ContractAddress,
        parameter: Parameter,
        method: EntrypointName,
        amount: Amount,
    ) -> CallContractResult<Self::ReturnValueType>;

    /// Like [`invoke_contract_raw`](Self::invoke_contract_raw), except that the
    /// parameter is automatically serialized. If the parameter already
    /// implements [`AsRef<[u8]>`](AsRef) or can be equivalently cheaply
    /// converted to a byte array, then
    /// [`invoke_contract_raw`](Self::invoke_contract_raw) should be
    /// used, since it avoids intermediate allocations.
    fn invoke_contract<P: Serial>(
        &mut self,
        to: &ContractAddress,
        parameter: &P,
        method: EntrypointName,
        amount: Amount,
    ) -> CallContractResult<Self::ReturnValueType> {
        let param = to_bytes(parameter);
        self.invoke_contract_raw(to, Parameter::new_unchecked(&param), method, amount)
    }

    /// Upgrade the module for this instance to a given module. The new module
    /// must contain a smart contract with a matching name.
    /// Invocations of this instance after the point of a successful upgrade,
    /// will use the new smart contract module. The remaining code after a
    /// successful upgrade in the same invokation is executed as normal.
    ///
    /// This will fail if:
    /// - The supplied module is not deployed.
    /// - The supplied module does not contain a smart contract with a name
    ///   matching this instance.
    /// - The supplied module is a version 0 smart contract module.
    fn upgrade(&mut self, module: ModuleReference) -> UpgradeResult;

    /// Invoke a given method of a contract with the amount and parameter
    /// provided. If invocation succeeds **and the state of the contract
    /// instance is not modified** then the return value is the return value
    /// of the contract that was invoked. The return value is present (i.e.,
    /// not [`None`]) if and only if a V1 contract was invoked. If the
    /// invocation succeeds but the state of the contract is modified then
    /// this method will panic.
    ///
    /// <div class="example-wrap" style="display:inline-block"><pre
    /// class="compile_fail" style="white-space:normal;font:inherit;">
    ///
    /// **Warning**: If the state of the contract was modified **prior**, i.e.,
    /// if a mutable reference obtained via
    /// [`state_mut`](HasHost::state_mut) was used to modify the state then
    /// the state must be manually stored via the
    /// [`commit_state`](HasHost::commit_state) function, otherwise it will not
    /// be seen by the callee.
    ///
    /// </pre></div>
    fn invoke_contract_raw_read_only(
        &self,
        to: &ContractAddress,
        parameter: Parameter<'_>,
        method: EntrypointName<'_>,
        amount: Amount,
    ) -> ReadOnlyCallContractResult<Self::ReturnValueType>;

    /// Like [`invoke_contract_raw_read_only`][0], except that the parameter is
    /// automatically serialized. If the parameter already implements
    /// [`AsRef<[u8]>`](AsRef) or can be equivalently cheaply converted to a
    /// byte array, then [`invoke_contract_raw`](Self::invoke_contract_raw)
    /// should be used, since it avoids intermediate allocations.
    ///
    /// [0]: Self::invoke_contract_raw_read_only
    ///
    /// <div class="example-wrap" style="display:inline-block"><pre
    /// class="compile_fail" style="white-space:normal;font:inherit;">
    ///
    /// **Warning**: If the state of the contract was modified **prior**, i.e.,
    /// if a mutable reference obtained via
    /// [`state_mut`](HasHost::state_mut) was used to modify the state then
    /// the state must be manually stored via the
    /// [`commit_state`](HasHost::commit_state) function, otherwise it will not
    /// be seen by the callee.
    ///
    /// </pre></div>
    fn invoke_contract_read_only<P: Serial>(
        &self,
        to: &ContractAddress,
        parameter: &P,
        method: EntrypointName,
        amount: Amount,
    ) -> ReadOnlyCallContractResult<Self::ReturnValueType> {
        let param = to_bytes(parameter);
        self.invoke_contract_raw_read_only(to, Parameter::new_unchecked(&param), method, amount)
    }

    /// Get the current exchange rates used by the chain. That is a Euro per
    /// Energy rate and micro CCD per Euro rate.
    fn exchange_rates(&self) -> ExchangeRates;

    /// Get the current public balance of an account. Here public means
    /// unencrypted or unshielded. See
    /// [`AccountBalance`](concordium_contracts_common::AccountBalance) for
    /// more. This query will fail if the provided address does not exist on
    /// chain.
    ///
    /// Any amount received by transfers during the transaction
    /// until the point of querying are reflected in this balance.
    ///
    /// ```ignore
    /// let balance_before = host.account_balance(account)?;
    /// host.invoke_transfer(&account, amount)?;
    /// let balance_after = host.account_balance(account)?; // balance_before + amount
    /// ```
    ///
    /// Note: Querying the account invoking this transaction, will return the
    /// current account balance subtracted the amount of CCD reserved for paying
    /// the entire energy limit and the amount sent as part of update
    /// transaction.
    fn account_balance(&self, address: AccountAddress) -> QueryAccountBalanceResult;

    /// Get the current balance of a contract instance.
    ///
    /// Any amount sent and received by transfers and invocations until the
    /// point of querying are reflected in this balance.
    /// This query will fail if the provided address does not exist on chain.
    ///
    /// ```ignore
    /// let balance_before = host.contract_balance(contract_address)?;
    /// host.invoke_contract(&contract_address, ..., amount)?;
    /// let balance_after = host.contract_balance(contract_address)?; // balance_before + amount
    /// ```
    ///
    /// Note: Querying the contract itself returns the balance of the contract
    /// including the amount transferred as part of the invocation.
    fn contract_balance(&self, address: ContractAddress) -> QueryContractBalanceResult;

    /// Get the account's public keys.
    fn account_public_keys(&self, address: AccountAddress) -> QueryAccountPublicKeysResult;

    /// Verify the signature with account's public keys.
    ///
    /// - `address` is the address of the account
    /// - `signatures` is the [`AccountSignatures`] that are to be checked
    /// - `data` is the data that the signatures are on.
    ///
    /// The response is an error if the account is missing, and if the
    /// signatures were correctly parsed then it is a boolean indicating
    /// whether the check succeeded or failed.
    fn check_account_signature(
        &self,
        address: AccountAddress,
        signatures: &AccountSignatures,
        data: &[u8],
    ) -> CheckAccountSignatureResult;

    /// Get the module reference of a contract instance.
    ///
    /// Note: after a successful [`Self::upgrade`], this will return the new
    /// module reference.
    #[cfg(feature = "p7")]
    fn contract_module_reference(
        &self,
        address: ContractAddress,
    ) -> QueryContractModuleReferenceResult;

    /// Get the contract name of a contract instance.
    #[cfg(feature = "p7")]
    fn contract_name(&self, address: ContractAddress) -> QueryContractNameResult;

    /// Get an immutable reference to the contract state.
    fn state(&self) -> &State;

    /// Get a mutable reference to the contract state.
    fn state_mut(&mut self) -> &mut State;

    /// Make sure the contract state is fully written out, so that any changes
    /// that were done in-memory up to the point in contract execution are
    /// reflected in the actual contract state maintained by the node.
    fn commit_state(&mut self);

    /// Get the state_builder for the contract state.
    fn state_builder(&mut self) -> &mut StateBuilder<Self::StateApiType>;

    /// Get a mutable reference to both the state and the builder.
    /// This is required due to limitations of the Rust type system, since
    /// otherwise it is not possible to get the reference to the state and
    /// the state builder at the same time. Once some incarnation of "view
    /// types" is stable this will likely be possible to remove, and the
    /// types of `state_builder` and `state_mut` can be refined.
    fn state_and_builder(&mut self) -> (&mut State, &mut StateBuilder<Self::StateApiType>);

    /// Get the contract's own current balance. Upon entry to the entrypoint the
    /// balance that is returned is the sum of balance of the contract at
    /// the time of the invocation and the amount that is being transferred to
    /// the contract.
    fn self_balance(&self) -> Amount;
}

/// A type that can be deleted from the state.
/// For simple types, such as `u8` and `String`, the `delete` methods is a
/// no-op. But for [`StateBox`][crate::StateBox], [`StateMap`][crate::StateMap],
/// and [`StateSet`][crate::StateSet], `delete` makes sure to the delete _all_
/// the necessary data from the state.
pub trait Deletable {
    /// Delete all items that this type owns in the state.
    fn delete(self);
}

/// Objects which can serve as loggers.
///
/// Logging functionality can be used by smart contracts to record events that
/// might be of interest to external parties. These events are not used on the
/// chain, and cannot be observed by other contracts, but they are stored by the
/// node, and can be queried to provide information to off-chain actors.
///
/// In v1 contracts logging is per section of execution (between
/// [`invoke_contract`](HasHost::invoke_contract) or
/// [`invoke_transfer`](HasHost::invoke_transfer) calls. In each section at most
/// `64` items may be logged.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`Logger`](crate::types::Logger) instead unless you intend to use
/// the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasLogger {
    /// Initialize a logger.
    fn init() -> Self;

    /// Log the given slice as-is. If logging is not successful an error will be
    /// returned. The event can be no bigger than `512` bytes.
    fn log_raw(&mut self, event: &[u8]) -> Result<(), LogError>;

    #[inline(always)]
    /// Log a serializable event by serializing it with a supplied serializer.
    /// Note that the serialized event must be no larger than `512` bytes.
    fn log<S: Serial>(&mut self, event: &S) -> Result<(), LogError> {
        let mut out = Vec::new();
        if event.serial(&mut out).is_err() {
            crate::trap(); // should not happen
        }
        self.log_raw(&out)
    }
}

/// Objects which provide cryptographic primitives.
///
/// # Deprecation notice
/// **This trait is deprecated along with
/// [`crate::test_infrastructure`].**
///
/// Use [`CryptoPrimitives`](crate::types::CryptoPrimitives) instead unless you
/// intend to use the deprecated test infrastructure.
///
/// See the [crate](../concordium_std/#deprecating-the-test_infrastructure)
/// documentation for more details.
pub trait HasCryptoPrimitives {
    /// Verify an ed25519 signature.
    fn verify_ed25519_signature(
        &self,
        public_key: PublicKeyEd25519,
        signature: SignatureEd25519,
        message: &[u8],
    ) -> bool;

    /// Verify an ecdsa signature over secp256k1 with the bitcoin-core
    /// implementation.
    fn verify_ecdsa_secp256k1_signature(
        &self,
        public_key: PublicKeyEcdsaSecp256k1,
        signature: SignatureEcdsaSecp256k1,
        message_hash: [u8; 32],
    ) -> bool;

    /// Hash the data using the SHA2-256 algorithm.
    fn hash_sha2_256(&self, data: &[u8]) -> HashSha2256;

    /// Hash the data using the SHA3-256 algorithm.
    fn hash_sha3_256(&self, data: &[u8]) -> HashSha3256;

    /// Hash the data using the Keccak-256 algorithm.
    fn hash_keccak_256(&self, data: &[u8]) -> HashKeccak256;
}

/// Add optimized unwrap behaviour that aborts the process instead of
/// panicking.
pub trait UnwrapAbort {
    /// The underlying result type of the unwrap, in case of success.
    type Unwrap;
    /// Unwrap or call [trap](./fn.trap.html). In contrast to
    /// the unwrap methods on [Option::unwrap](https://doc.rust-lang.org/std/option/enum.Option.html#method.unwrap)
    /// this method will tend to produce smaller code, at the cost of the
    /// ability to handle the panic.
    /// This is intended to be used only in `Wasm` code, where panics cannot be
    /// handled anyhow.
    fn unwrap_abort(self) -> Self::Unwrap;
}

/// Analogue of the `expect` methods on types such as [Option](https://doc.rust-lang.org/std/option/enum.Option.html),
/// but useful in a Wasm setting.
pub trait ExpectReport {
    type Unwrap;
    /// Like the default `expect` on, e.g., `Result`, but calling
    /// [fail](macro.fail.html) with the given message, instead of `panic`.
    fn expect_report(self, msg: &str) -> Self::Unwrap;
}

/// Analogue of the `expect_err` methods on [Result](https://doc.rust-lang.org/std/result/enum.Result.html),
/// but useful in a Wasm setting.
pub trait ExpectErrReport {
    type Unwrap;
    /// Like the default `expect_err` on, e.g., `Result`, but calling
    /// [fail](macro.fail.html) with the given message, instead of `panic`.
    fn expect_err_report(self, msg: &str) -> Self::Unwrap;
}

/// Analogue of the `expect_none` methods on [Option](https://doc.rust-lang.org/std/option/enum.Option.html),
/// but useful in a Wasm setting.
pub trait ExpectNoneReport {
    /// Like the default `expect_none_report` on, e.g., `Option`, but calling
    /// [fail](macro.fail.html) with the given message, instead of `panic`.
    fn expect_none_report(self, msg: &str);
}

/// The `DeserialWithState` trait provides a means of reading structures from
/// byte-sources ([`Read`]) for types that also need a reference to a
/// [`HasStateApi`] type.
///
/// Types that need a reference to the state include
/// [`StateBox`][crate::StateBox], [`StateMap`][crate::StateMap],
/// [`StateSet`][crate::StateSet], and structs or enums that contain one of
/// these types.
pub trait DeserialWithState<S>: Sized
where
    S: HasStateApi, {
    /// Attempt to read a structure from a given source and state, failing if
    /// an error occurs during deserialization or reading.
    fn deserial_with_state<R: Read>(state: &S, source: &mut R) -> ParseResult<Self>;
}

/// The `DeserialCtxWithState` trait provides a means of reading structures from
/// byte-sources ([`Read`]) using contextual information for types that also
/// need a reference to a [`HasStateApi`] type. The trait is a combination
/// of the [`DeserialCtx`] and [`DeserialWithState`] traits, which each has
/// additional documentation.
///
/// This trait is primarily used when deriving [`DeserialWithState`] for struct
/// or enums where both contextual information and the state is present.
///
/// For example:
/// ```no_run
/// # use concordium_std::*;
/// #[derive(DeserialWithState)]
/// #[concordium(state_parameter = "S")]
/// struct MyStruct<S: HasStateApi> {
///     #[concordium(size_length = 2)]
///     a: String, // Gets the contextual size_length information.
///     b: StateBox<u8, S>, // Needs a HasStateApi type
/// }
/// ```
pub trait DeserialCtxWithState<S>: Sized
where
    S: HasStateApi, {
    /// Attempt to read a structure from a given source, context, and state,
    /// failing if an error occurs during deserialization or reading.
    fn deserial_ctx_with_state<R: Read>(
        size_length: schema::SizeLength,
        ensure_ordered: bool,
        state: &S,
        source: &mut R,
    ) -> ParseResult<Self>;
}