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
use crate::error::{OneYoctoAttachError, PrivateCallError};
use crate::prelude::{NearGas, H256};
use aurora_engine_types::account_id::AccountId;

pub const DEFAULT_PREPAID_GAS: NearGas = NearGas::new(300_000_000_000_000);

/// Timestamp represented by the number of nanoseconds since the Unix Epoch.
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
pub struct Timestamp(u64);

impl Timestamp {
    #[must_use]
    pub const fn new(ns: u64) -> Self {
        Self(ns)
    }

    #[must_use]
    pub const fn nanos(&self) -> u64 {
        self.0
    }

    #[must_use]
    pub const fn millis(&self) -> u64 {
        self.0 / 1_000_000
    }

    #[must_use]
    pub const fn secs(&self) -> u64 {
        self.0 / 1_000_000_000
    }
}

/// Returns information about the NEAR context in which the
/// transaction is executing. In the case of a standalone binary,
/// independent of NEAR these values would need to be mocked or otherwise
/// passed in from an external source.
pub trait Env {
    /// Account ID that signed the transaction.
    fn signer_account_id(&self) -> AccountId;
    /// Account ID of the currently executing contract.
    fn current_account_id(&self) -> AccountId;
    /// Account ID which called the current contract.
    fn predecessor_account_id(&self) -> AccountId;
    /// Height of the current block.
    fn block_height(&self) -> u64;
    /// Timestamp (in ns) of the current block.
    fn block_timestamp(&self) -> Timestamp;
    /// Amount of NEAR attached to current call
    fn attached_deposit(&self) -> u128;
    /// Random seed generated for the current block
    fn random_seed(&self) -> H256;
    /// Prepaid NEAR Gas
    fn prepaid_gas(&self) -> NearGas;

    fn assert_private_call(&self) -> Result<(), PrivateCallError> {
        if self.predecessor_account_id() == self.current_account_id() {
            Ok(())
        } else {
            Err(PrivateCallError)
        }
    }

    fn assert_one_yocto(&self) -> Result<(), OneYoctoAttachError> {
        if self.attached_deposit() == 1 {
            Ok(())
        } else {
            Err(OneYoctoAttachError)
        }
    }
}

/// Fully in-memory implementation of the blockchain environment with
/// fixed values for all the fields.
#[derive(Default, Debug, Clone, PartialEq, Eq)]
pub struct Fixed {
    pub signer_account_id: AccountId,
    pub current_account_id: AccountId,
    pub predecessor_account_id: AccountId,
    pub block_height: u64,
    pub block_timestamp: Timestamp,
    pub attached_deposit: u128,
    pub random_seed: H256,
    pub prepaid_gas: NearGas,
}

impl Env for Fixed {
    fn signer_account_id(&self) -> AccountId {
        self.signer_account_id.clone()
    }

    fn current_account_id(&self) -> AccountId {
        self.current_account_id.clone()
    }

    fn predecessor_account_id(&self) -> AccountId {
        self.predecessor_account_id.clone()
    }

    fn block_height(&self) -> u64 {
        self.block_height
    }

    fn block_timestamp(&self) -> Timestamp {
        self.block_timestamp
    }

    fn attached_deposit(&self) -> u128 {
        self.attached_deposit
    }

    fn random_seed(&self) -> H256 {
        self.random_seed
    }

    fn prepaid_gas(&self) -> NearGas {
        self.prepaid_gas
    }
}