Przeglądaj źródła

Add near-primitives-light instead of an near-primitives

develop
Silvestr Predko 2 lat temu
rodzic
commit
a1cec0c794

+ 1
- 1
.github/workflows/ci.yml Wyświetl plik

@@ -113,4 +113,4 @@ jobs:
113 113
           (cd near-smartcontracts && docker compose -f docker-compose.yml -f docker-compose.tests.yml up -d --no-build)
114 114
       - uses: actions/checkout@v3
115 115
       - name: Run tests for [web]
116
-        run: docker compose up
116
+        run: docker compose up --abort-on-container-exit

+ 0
- 3
.vscode/settings.json Wyświetl plik

@@ -1,3 +0,0 @@
1
-{
2
-    "rust-analyzer.cargo.target": "wasm32-unknown-unknown"
3
-}

+ 1
- 1
Cargo.toml Wyświetl plik

@@ -1,5 +1,5 @@
1 1
 [workspace]
2
-members = ["web-client", "near-rpc", "common-api"]
2
+members = ["web-client", "near-rpc", "common-api", "near-primitives-light"]
3 3
 
4 4
 [profile.release]
5 5
 codegen-units = 1

+ 16
- 0
near-primitives-light/Cargo.toml Wyświetl plik

@@ -0,0 +1,16 @@
1
+[package]
2
+name = "near-primitives-light"
3
+version = "0.1.0"
4
+edition = "2021"
5
+authors = ["silvestr@relayz.io"]
6
+description = """
7
+Copy-paste from a https://github.com/near/nearcore.
8
+It's a reduced implementation of near primitives.
9
+"""
10
+
11
+[dependencies]
12
+borsh = "0.9"
13
+common-api = { path = "../common-api" }
14
+chrono = { version = "0.4", features = ["serde"] }
15
+serde = { version = "1", default-features = false, features = ["derive", "rc"] }
16
+near-primitives-core = "0.15"

+ 823
- 0
near-primitives-light/src/errors.rs Wyświetl plik

@@ -0,0 +1,823 @@
1
+use serde::{Deserialize, Serialize};
2
+use std::fmt::{Debug, Display};
3
+
4
+use near_primitives_core::{
5
+    hash::CryptoHash,
6
+    serialize::dec_format,
7
+    types::{AccountId, Balance, Gas, Nonce},
8
+};
9
+
10
+use common_api::crypto::prelude::*;
11
+
12
+use borsh::{BorshDeserialize, BorshSerialize};
13
+
14
+/// Error returned in the ExecutionOutcome in case of failure
15
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
16
+pub enum TxExecutionError {
17
+    /// An error happened during Action execution
18
+    ActionError(ActionError),
19
+    /// An error happened during Transaction execution
20
+    InvalidTxError(InvalidTxError),
21
+}
22
+
23
+impl std::error::Error for TxExecutionError {}
24
+
25
+impl Display for TxExecutionError {
26
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
27
+        match self {
28
+            TxExecutionError::ActionError(e) => write!(f, "{}", e),
29
+            TxExecutionError::InvalidTxError(e) => write!(f, "{}", e),
30
+        }
31
+    }
32
+}
33
+
34
+impl From<ActionError> for TxExecutionError {
35
+    fn from(error: ActionError) -> Self {
36
+        TxExecutionError::ActionError(error)
37
+    }
38
+}
39
+
40
+impl From<InvalidTxError> for TxExecutionError {
41
+    fn from(error: InvalidTxError) -> Self {
42
+        TxExecutionError::InvalidTxError(error)
43
+    }
44
+}
45
+
46
+/// Error returned from `Runtime::apply`
47
+#[derive(Debug, Clone, PartialEq, Eq)]
48
+pub enum RuntimeError {
49
+    /// An unexpected integer overflow occurred. The likely issue is an invalid state or the transition.
50
+    UnexpectedIntegerOverflow,
51
+    /// An error happened during TX verification and account charging. It's likely the chunk is invalid.
52
+    /// and should be challenged.
53
+    InvalidTxError(InvalidTxError),
54
+    /// Unexpected error which is typically related to the node storage corruption.
55
+    /// It's possible the input state is invalid or malicious.
56
+    StorageError(StorageError),
57
+    /// An error happens if `check_balance` fails, which is likely an indication of an invalid state.
58
+    BalanceMismatchError(BalanceMismatchError),
59
+    /// The incoming receipt didn't pass the validation, it's likely a malicious behaviour.
60
+    ReceiptValidationError(ReceiptValidationError),
61
+    /// Error when accessing validator information. Happens inside epoch manager.
62
+    ValidatorError(EpochError),
63
+}
64
+
65
+impl std::fmt::Display for RuntimeError {
66
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
67
+        f.write_str(&format!("{:?}", self))
68
+    }
69
+}
70
+
71
+impl std::error::Error for RuntimeError {}
72
+
73
+/// Internal
74
+#[derive(Debug, Clone, PartialEq, Eq)]
75
+pub enum StorageError {
76
+    /// Key-value db internal failure
77
+    StorageInternalError,
78
+    /// Storage is PartialStorage and requested a missing trie node
79
+    TrieNodeMissing,
80
+    /// Either invalid state or key-value db is corrupted.
81
+    /// For PartialStorage it cannot be corrupted.
82
+    /// Error message is unreliable and for debugging purposes only. It's also probably ok to
83
+    /// panic in every place that produces this error.
84
+    /// We can check if db is corrupted by verifying everything in the state trie.
85
+    StorageInconsistentState(String),
86
+    /// Error from flat storage
87
+    FlatStorageError(String),
88
+}
89
+
90
+impl std::fmt::Display for StorageError {
91
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
92
+        f.write_str(&format!("{:?}", self))
93
+    }
94
+}
95
+
96
+impl std::error::Error for StorageError {}
97
+
98
+/// An error happened during TX execution
99
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
100
+pub enum InvalidTxError {
101
+    /// Happens if a wrong AccessKey used or AccessKey has not enough permissions
102
+    InvalidAccessKeyError(InvalidAccessKeyError),
103
+    /// TX signer_id is not a valid [`AccountId`]
104
+    InvalidSignerId { signer_id: String },
105
+    /// TX signer_id is not found in a storage
106
+    SignerDoesNotExist { signer_id: AccountId },
107
+    /// Transaction nonce must be `account[access_key].nonce + 1`.
108
+    InvalidNonce { tx_nonce: Nonce, ak_nonce: Nonce },
109
+    /// Transaction nonce is larger than the upper bound given by the block height
110
+    NonceTooLarge { tx_nonce: Nonce, upper_bound: Nonce },
111
+    /// TX receiver_id is not a valid AccountId
112
+    InvalidReceiverId { receiver_id: String },
113
+    /// TX signature is not valid
114
+    InvalidSignature,
115
+    /// Account does not have enough balance to cover TX cost
116
+    NotEnoughBalance {
117
+        signer_id: AccountId,
118
+        #[serde(with = "dec_format")]
119
+        balance: Balance,
120
+        #[serde(with = "dec_format")]
121
+        cost: Balance,
122
+    },
123
+    /// Signer account doesn't have enough balance after transaction.
124
+    LackBalanceForState {
125
+        /// An account which doesn't have enough balance to cover storage.
126
+        signer_id: AccountId,
127
+        /// Required balance to cover the state.
128
+        #[serde(with = "dec_format")]
129
+        amount: Balance,
130
+    },
131
+    /// An integer overflow occurred during transaction cost estimation.
132
+    CostOverflow,
133
+    /// Transaction parent block hash doesn't belong to the current chain
134
+    InvalidChain,
135
+    /// Transaction has expired
136
+    Expired,
137
+    /// An error occurred while validating actions of a Transaction.
138
+    ActionsValidation(ActionsValidationError),
139
+    /// The size of serialized transaction exceeded the limit.
140
+    TransactionSizeExceeded { size: u64, limit: u64 },
141
+}
142
+
143
+impl std::error::Error for InvalidTxError {}
144
+
145
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
146
+pub enum InvalidAccessKeyError {
147
+    /// The access key identified by the `public_key` doesn't exist for the account
148
+    AccessKeyNotFound {
149
+        account_id: AccountId,
150
+        public_key: Ed25519PublicKey,
151
+    },
152
+    /// Transaction `receiver_id` doesn't match the access key receiver_id
153
+    ReceiverMismatch {
154
+        tx_receiver: AccountId,
155
+        ak_receiver: String,
156
+    },
157
+    /// Transaction method name isn't allowed by the access key
158
+    MethodNameMismatch { method_name: String },
159
+    /// Transaction requires a full permission access key.
160
+    RequiresFullAccess,
161
+    /// Access Key does not have enough allowance to cover transaction cost
162
+    NotEnoughAllowance {
163
+        account_id: AccountId,
164
+        public_key: Ed25519PublicKey,
165
+        #[serde(with = "dec_format")]
166
+        allowance: Balance,
167
+        #[serde(with = "dec_format")]
168
+        cost: Balance,
169
+    },
170
+    /// Having a deposit with a function call action is not allowed with a function call access key.
171
+    DepositWithFunctionCall,
172
+}
173
+
174
+/// Describes the error for validating a list of actions.
175
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
176
+pub enum ActionsValidationError {
177
+    /// The delete action must be a final aciton in transaction
178
+    DeleteActionMustBeFinal,
179
+    /// The total prepaid gas (for all given actions) exceeded the limit.
180
+    TotalPrepaidGasExceeded { total_prepaid_gas: Gas, limit: Gas },
181
+    /// The number of actions exceeded the given limit.
182
+    TotalNumberOfActionsExceeded {
183
+        total_number_of_actions: u64,
184
+        limit: u64,
185
+    },
186
+    /// The total number of bytes of the method names exceeded the limit in a Add Key action.
187
+    AddKeyMethodNamesNumberOfBytesExceeded {
188
+        total_number_of_bytes: u64,
189
+        limit: u64,
190
+    },
191
+    /// The length of some method name exceeded the limit in a Add Key action.
192
+    AddKeyMethodNameLengthExceeded { length: u64, limit: u64 },
193
+    /// Integer overflow during a compute.
194
+    IntegerOverflow,
195
+    /// Invalid account ID.
196
+    InvalidAccountId { account_id: String },
197
+    /// The size of the contract code exceeded the limit in a DeployContract action.
198
+    ContractSizeExceeded { size: u64, limit: u64 },
199
+    /// The length of the method name exceeded the limit in a Function Call action.
200
+    FunctionCallMethodNameLengthExceeded { length: u64, limit: u64 },
201
+    /// The length of the arguments exceeded the limit in a Function Call action.
202
+    FunctionCallArgumentsLengthExceeded { length: u64, limit: u64 },
203
+    /// An attempt to stake with a public key that is not convertible to ristretto.
204
+    UnsuitableStakingKey { public_key: Ed25519PublicKey },
205
+    /// The attached amount of gas in a FunctionCall action has to be a positive number.
206
+    FunctionCallZeroAttachedGas,
207
+}
208
+
209
+/// Describes the error for validating a receipt.
210
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
211
+pub enum ReceiptValidationError {
212
+    /// The `predecessor_id` of a Receipt is not valid.
213
+    InvalidPredecessorId { account_id: String },
214
+    /// The `receiver_id` of a Receipt is not valid.
215
+    InvalidReceiverId { account_id: String },
216
+    /// The `signer_id` of an ActionReceipt is not valid.
217
+    InvalidSignerId { account_id: String },
218
+    /// The `receiver_id` of a DataReceiver within an ActionReceipt is not valid.
219
+    InvalidDataReceiverId { account_id: String },
220
+    /// The length of the returned data exceeded the limit in a DataReceipt.
221
+    ReturnedValueLengthExceeded { length: u64, limit: u64 },
222
+    /// The number of input data dependencies exceeds the limit in an ActionReceipt.
223
+    NumberInputDataDependenciesExceeded {
224
+        number_of_input_data_dependencies: u64,
225
+        limit: u64,
226
+    },
227
+    /// An error occurred while validating actions of an ActionReceipt.
228
+    ActionsValidation(ActionsValidationError),
229
+}
230
+
231
+impl Display for ReceiptValidationError {
232
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
233
+        match self {
234
+            ReceiptValidationError::InvalidPredecessorId { account_id } => {
235
+                write!(f, "The predecessor_id `{}` of a Receipt is not valid.", account_id)
236
+            }
237
+            ReceiptValidationError::InvalidReceiverId { account_id } => {
238
+                write!(f, "The receiver_id `{}` of a Receipt is not valid.", account_id)
239
+            }
240
+            ReceiptValidationError::InvalidSignerId { account_id } => {
241
+                write!(f, "The signer_id `{}` of an ActionReceipt is not valid.", account_id)
242
+            }
243
+            ReceiptValidationError::InvalidDataReceiverId { account_id } => write!(
244
+                f,
245
+                "The receiver_id `{}` of a DataReceiver within an ActionReceipt is not valid.",
246
+                account_id
247
+            ),
248
+            ReceiptValidationError::ReturnedValueLengthExceeded { length, limit } => write!(
249
+                f,
250
+                "The length of the returned data {} exceeded the limit {} in a DataReceipt",
251
+                length, limit
252
+            ),
253
+            ReceiptValidationError::NumberInputDataDependenciesExceeded { number_of_input_data_dependencies, limit } => write!(
254
+                f,
255
+                "The number of input data dependencies {} exceeded the limit {} in an ActionReceipt",
256
+                number_of_input_data_dependencies, limit
257
+            ),
258
+            ReceiptValidationError::ActionsValidation(e) => write!(f, "{}", e),
259
+        }
260
+    }
261
+}
262
+
263
+impl std::error::Error for ReceiptValidationError {}
264
+
265
+impl Display for ActionsValidationError {
266
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
267
+        match self {
268
+            ActionsValidationError::DeleteActionMustBeFinal => {
269
+                write!(f, "The delete action must be the last action in transaction")
270
+            }
271
+            ActionsValidationError::TotalPrepaidGasExceeded { total_prepaid_gas, limit } => {
272
+                write!(f, "The total prepaid gas {} exceeds the limit {}", total_prepaid_gas, limit)
273
+            }
274
+            ActionsValidationError::TotalNumberOfActionsExceeded {total_number_of_actions, limit } => {
275
+                write!(
276
+                    f,
277
+                    "The total number of actions {} exceeds the limit {}",
278
+                    total_number_of_actions, limit
279
+                )
280
+            }
281
+            ActionsValidationError::AddKeyMethodNamesNumberOfBytesExceeded { total_number_of_bytes, limit } => write!(
282
+                f,
283
+                "The total number of bytes in allowed method names {} exceeds the maximum allowed number {} in a AddKey action",
284
+                total_number_of_bytes, limit
285
+            ),
286
+            ActionsValidationError::AddKeyMethodNameLengthExceeded { length, limit } => write!(
287
+                f,
288
+                "The length of some method name {} exceeds the maximum allowed length {} in a AddKey action",
289
+                length, limit
290
+            ),
291
+            ActionsValidationError::IntegerOverflow => write!(
292
+                f,
293
+                "Integer overflow during a compute",
294
+            ),
295
+            ActionsValidationError::InvalidAccountId { account_id } => write!(
296
+                f,
297
+                "Invalid account ID `{}`",
298
+                account_id
299
+            ),
300
+            ActionsValidationError::ContractSizeExceeded { size, limit } => write!(
301
+                f,
302
+                "The length of the contract size {} exceeds the maximum allowed size {} in a DeployContract action",
303
+                size, limit
304
+            ),
305
+            ActionsValidationError::FunctionCallMethodNameLengthExceeded { length, limit } => write!(
306
+                f,
307
+                "The length of the method name {} exceeds the maximum allowed length {} in a FunctionCall action",
308
+                length, limit
309
+            ),
310
+            ActionsValidationError::FunctionCallArgumentsLengthExceeded { length, limit } => write!(
311
+                f,
312
+                "The length of the arguments {} exceeds the maximum allowed length {} in a FunctionCall action",
313
+                length, limit
314
+            ),
315
+            ActionsValidationError::UnsuitableStakingKey { public_key } => write!(
316
+                f,
317
+                "The staking key must be ristretto compatible ED25519 key. {} is provided instead.",
318
+                public_key,
319
+            ),
320
+            ActionsValidationError::FunctionCallZeroAttachedGas => write!(
321
+                f,
322
+                "The attached amount of gas in a FunctionCall action has to be a positive number",
323
+            ),
324
+        }
325
+    }
326
+}
327
+
328
+impl std::error::Error for ActionsValidationError {}
329
+
330
+/// An error happened during Action execution
331
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
332
+pub struct ActionError {
333
+    /// Index of the failed action in the transaction.
334
+    /// Action index is not defined if ActionError.kind is `ActionErrorKind::LackBalanceForState`
335
+    pub index: Option<u64>,
336
+    /// The kind of ActionError happened
337
+    pub kind: ActionErrorKind,
338
+}
339
+
340
+impl std::error::Error for ActionError {}
341
+
342
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
343
+pub enum ActionErrorKind {
344
+    /// Happens when CreateAccount action tries to create an account with account_id which is already exists in the storage
345
+    AccountAlreadyExists { account_id: AccountId },
346
+    /// Happens when TX receiver_id doesn't exist (but action is not Action::CreateAccount)
347
+    AccountDoesNotExist { account_id: AccountId },
348
+    /// A top-level account ID can only be created by registrar.
349
+    CreateAccountOnlyByRegistrar {
350
+        account_id: AccountId,
351
+        registrar_account_id: AccountId,
352
+        predecessor_id: AccountId,
353
+    },
354
+    /// A newly created account must be under a namespace of the creator account
355
+    CreateAccountNotAllowed {
356
+        account_id: AccountId,
357
+        predecessor_id: AccountId,
358
+    },
359
+    /// Administrative actions like `DeployContract`, `Stake`, `AddKey`, `DeleteKey`. can be proceed only if sender=receiver
360
+    /// or the first TX action is a `CreateAccount` action
361
+    ActorNoPermission {
362
+        account_id: AccountId,
363
+        actor_id: AccountId,
364
+    },
365
+    /// Account tries to remove an access key that doesn't exist
366
+    DeleteKeyDoesNotExist {
367
+        account_id: AccountId,
368
+        public_key: Ed25519PublicKey,
369
+    },
370
+    /// The public key is already used for an existing access key
371
+    AddKeyAlreadyExists {
372
+        account_id: AccountId,
373
+        public_key: Ed25519PublicKey,
374
+    },
375
+    /// Account is staking and can not be deleted
376
+    DeleteAccountStaking { account_id: AccountId },
377
+    /// ActionReceipt can't be completed, because the remaining balance will not be enough to cover storage.
378
+    LackBalanceForState {
379
+        /// An account which needs balance
380
+        account_id: AccountId,
381
+        /// Balance required to complete an action.
382
+        #[serde(with = "dec_format")]
383
+        amount: Balance,
384
+    },
385
+    /// Account is not yet staked, but tries to unstake
386
+    TriesToUnstake { account_id: AccountId },
387
+    /// The account doesn't have enough balance to increase the stake.
388
+    TriesToStake {
389
+        account_id: AccountId,
390
+        #[serde(with = "dec_format")]
391
+        stake: Balance,
392
+        #[serde(with = "dec_format")]
393
+        locked: Balance,
394
+        #[serde(with = "dec_format")]
395
+        balance: Balance,
396
+    },
397
+    InsufficientStake {
398
+        account_id: AccountId,
399
+        #[serde(with = "dec_format")]
400
+        stake: Balance,
401
+        #[serde(with = "dec_format")]
402
+        minimum_stake: Balance,
403
+    },
404
+    /// Error occurs when a `CreateAccount` action is called on hex-characters
405
+    /// account of length 64.  See implicit account creation NEP:
406
+    /// <https://github.com/nearprotocol/NEPs/pull/71>.
407
+    OnlyImplicitAccountCreationAllowed { account_id: AccountId },
408
+    /// Delete account whose state is large is temporarily banned.
409
+    DeleteAccountWithLargeState { account_id: AccountId },
410
+}
411
+
412
+impl From<ActionErrorKind> for ActionError {
413
+    fn from(e: ActionErrorKind) -> ActionError {
414
+        ActionError {
415
+            index: None,
416
+            kind: e,
417
+        }
418
+    }
419
+}
420
+
421
+impl Display for InvalidTxError {
422
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
423
+        match self {
424
+            InvalidTxError::InvalidSignerId { signer_id } => {
425
+                write!(
426
+                    f,
427
+                    "Invalid signer account ID {:?} according to requirements",
428
+                    signer_id
429
+                )
430
+            }
431
+            InvalidTxError::SignerDoesNotExist { signer_id } => {
432
+                write!(f, "Signer {:?} does not exist", signer_id)
433
+            }
434
+            InvalidTxError::InvalidAccessKeyError(access_key_error) => {
435
+                Display::fmt(&access_key_error, f)
436
+            }
437
+            InvalidTxError::InvalidNonce { tx_nonce, ak_nonce } => write!(
438
+                f,
439
+                "Transaction nonce {} must be larger than nonce of the used access key {}",
440
+                tx_nonce, ak_nonce
441
+            ),
442
+            InvalidTxError::InvalidReceiverId { receiver_id } => {
443
+                write!(
444
+                    f,
445
+                    "Invalid receiver account ID {:?} according to requirements",
446
+                    receiver_id
447
+                )
448
+            }
449
+            InvalidTxError::InvalidSignature => {
450
+                write!(f, "Transaction is not signed with the given public key")
451
+            }
452
+            InvalidTxError::NotEnoughBalance {
453
+                signer_id,
454
+                balance,
455
+                cost,
456
+            } => write!(
457
+                f,
458
+                "Sender {:?} does not have enough balance {} for operation costing {}",
459
+                signer_id, balance, cost
460
+            ),
461
+            InvalidTxError::LackBalanceForState { signer_id, amount } => {
462
+                write!(f, "Failed to execute, because the account {:?} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more", signer_id, amount)
463
+            }
464
+            InvalidTxError::CostOverflow => {
465
+                write!(f, "Transaction gas or balance cost is too high")
466
+            }
467
+            InvalidTxError::InvalidChain => {
468
+                write!(
469
+                    f,
470
+                    "Transaction parent block hash doesn't belong to the current chain"
471
+                )
472
+            }
473
+            InvalidTxError::Expired => {
474
+                write!(f, "Transaction has expired")
475
+            }
476
+            InvalidTxError::ActionsValidation(error) => {
477
+                write!(f, "Transaction actions validation error: {}", error)
478
+            }
479
+            InvalidTxError::NonceTooLarge {
480
+                tx_nonce,
481
+                upper_bound,
482
+            } => {
483
+                write!(
484
+                    f,
485
+                    "Transaction nonce {} must be smaller than the access key nonce upper bound {}",
486
+                    tx_nonce, upper_bound
487
+                )
488
+            }
489
+            InvalidTxError::TransactionSizeExceeded { size, limit } => {
490
+                write!(
491
+                    f,
492
+                    "Size of serialized transaction {} exceeded the limit {}",
493
+                    size, limit
494
+                )
495
+            }
496
+        }
497
+    }
498
+}
499
+
500
+impl From<InvalidAccessKeyError> for InvalidTxError {
501
+    fn from(error: InvalidAccessKeyError) -> Self {
502
+        InvalidTxError::InvalidAccessKeyError(error)
503
+    }
504
+}
505
+
506
+impl Display for InvalidAccessKeyError {
507
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
508
+        match self {
509
+            InvalidAccessKeyError::AccessKeyNotFound {
510
+                account_id,
511
+                public_key,
512
+            } => write!(
513
+                f,
514
+                "Signer {:?} doesn't have access key with the given public_key {}",
515
+                account_id, public_key
516
+            ),
517
+            InvalidAccessKeyError::ReceiverMismatch {
518
+                tx_receiver,
519
+                ak_receiver,
520
+            } => write!(
521
+                f,
522
+                "Transaction receiver_id {:?} doesn't match the access key receiver_id {:?}",
523
+                tx_receiver, ak_receiver
524
+            ),
525
+            InvalidAccessKeyError::MethodNameMismatch { method_name } => write!(
526
+                f,
527
+                "Transaction method name {:?} isn't allowed by the access key",
528
+                method_name
529
+            ),
530
+            InvalidAccessKeyError::RequiresFullAccess => {
531
+                write!(f, "Invalid access key type. Full-access keys are required for transactions that have multiple or non-function-call actions")
532
+            }
533
+            InvalidAccessKeyError::NotEnoughAllowance {
534
+                account_id,
535
+                public_key,
536
+                allowance,
537
+                cost,
538
+            } => write!(
539
+                f,
540
+                "Access Key {:?}:{} does not have enough balance {} for transaction costing {}",
541
+                account_id, public_key, allowance, cost
542
+            ),
543
+            InvalidAccessKeyError::DepositWithFunctionCall => {
544
+                write!(f, "Having a deposit with a function call action is not allowed with a function call access key.")
545
+            }
546
+        }
547
+    }
548
+}
549
+
550
+impl std::error::Error for InvalidAccessKeyError {}
551
+
552
+/// Happens when the input balance doesn't match the output balance in Runtime apply.
553
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
554
+pub struct BalanceMismatchError {
555
+    // Input balances
556
+    #[serde(with = "dec_format")]
557
+    pub incoming_validator_rewards: Balance,
558
+    #[serde(with = "dec_format")]
559
+    pub initial_accounts_balance: Balance,
560
+    #[serde(with = "dec_format")]
561
+    pub incoming_receipts_balance: Balance,
562
+    #[serde(with = "dec_format")]
563
+    pub processed_delayed_receipts_balance: Balance,
564
+    #[serde(with = "dec_format")]
565
+    pub initial_postponed_receipts_balance: Balance,
566
+    // Output balances
567
+    #[serde(with = "dec_format")]
568
+    pub final_accounts_balance: Balance,
569
+    #[serde(with = "dec_format")]
570
+    pub outgoing_receipts_balance: Balance,
571
+    #[serde(with = "dec_format")]
572
+    pub new_delayed_receipts_balance: Balance,
573
+    #[serde(with = "dec_format")]
574
+    pub final_postponed_receipts_balance: Balance,
575
+    #[serde(with = "dec_format")]
576
+    pub tx_burnt_amount: Balance,
577
+    #[serde(with = "dec_format")]
578
+    pub slashed_burnt_amount: Balance,
579
+    #[serde(with = "dec_format")]
580
+    pub other_burnt_amount: Balance,
581
+}
582
+
583
+impl Display for BalanceMismatchError {
584
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
585
+        // Using saturating add to avoid overflow in display
586
+        let initial_balance = self
587
+            .incoming_validator_rewards
588
+            .saturating_add(self.initial_accounts_balance)
589
+            .saturating_add(self.incoming_receipts_balance)
590
+            .saturating_add(self.processed_delayed_receipts_balance)
591
+            .saturating_add(self.initial_postponed_receipts_balance);
592
+        let final_balance = self
593
+            .final_accounts_balance
594
+            .saturating_add(self.outgoing_receipts_balance)
595
+            .saturating_add(self.new_delayed_receipts_balance)
596
+            .saturating_add(self.final_postponed_receipts_balance)
597
+            .saturating_add(self.tx_burnt_amount)
598
+            .saturating_add(self.slashed_burnt_amount)
599
+            .saturating_add(self.other_burnt_amount);
600
+        write!(
601
+            f,
602
+            "Balance Mismatch Error. The input balance {} doesn't match output balance {}\n\
603
+             Inputs:\n\
604
+             \tIncoming validator rewards sum: {}\n\
605
+             \tInitial accounts balance sum: {}\n\
606
+             \tIncoming receipts balance sum: {}\n\
607
+             \tProcessed delayed receipts balance sum: {}\n\
608
+             \tInitial postponed receipts balance sum: {}\n\
609
+             Outputs:\n\
610
+             \tFinal accounts balance sum: {}\n\
611
+             \tOutgoing receipts balance sum: {}\n\
612
+             \tNew delayed receipts balance sum: {}\n\
613
+             \tFinal postponed receipts balance sum: {}\n\
614
+             \tTx fees burnt amount: {}\n\
615
+             \tSlashed amount: {}\n\
616
+             \tOther burnt amount: {}",
617
+            initial_balance,
618
+            final_balance,
619
+            self.incoming_validator_rewards,
620
+            self.initial_accounts_balance,
621
+            self.incoming_receipts_balance,
622
+            self.processed_delayed_receipts_balance,
623
+            self.initial_postponed_receipts_balance,
624
+            self.final_accounts_balance,
625
+            self.outgoing_receipts_balance,
626
+            self.new_delayed_receipts_balance,
627
+            self.final_postponed_receipts_balance,
628
+            self.tx_burnt_amount,
629
+            self.slashed_burnt_amount,
630
+            self.other_burnt_amount,
631
+        )
632
+    }
633
+}
634
+
635
+impl std::error::Error for BalanceMismatchError {}
636
+
637
+#[derive(BorshSerialize, BorshDeserialize, Debug, Clone, PartialEq, Eq)]
638
+pub struct IntegerOverflowError;
639
+
640
+impl std::fmt::Display for IntegerOverflowError {
641
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
642
+        f.write_str(&format!("{:?}", self))
643
+    }
644
+}
645
+
646
+impl std::error::Error for IntegerOverflowError {}
647
+
648
+impl From<IntegerOverflowError> for InvalidTxError {
649
+    fn from(_: IntegerOverflowError) -> Self {
650
+        InvalidTxError::CostOverflow
651
+    }
652
+}
653
+
654
+impl From<IntegerOverflowError> for RuntimeError {
655
+    fn from(_: IntegerOverflowError) -> Self {
656
+        RuntimeError::UnexpectedIntegerOverflow
657
+    }
658
+}
659
+
660
+impl From<StorageError> for RuntimeError {
661
+    fn from(e: StorageError) -> Self {
662
+        RuntimeError::StorageError(e)
663
+    }
664
+}
665
+
666
+impl From<BalanceMismatchError> for RuntimeError {
667
+    fn from(e: BalanceMismatchError) -> Self {
668
+        RuntimeError::BalanceMismatchError(e)
669
+    }
670
+}
671
+
672
+impl From<InvalidTxError> for RuntimeError {
673
+    fn from(e: InvalidTxError) -> Self {
674
+        RuntimeError::InvalidTxError(e)
675
+    }
676
+}
677
+
678
+impl From<EpochError> for RuntimeError {
679
+    fn from(e: EpochError) -> Self {
680
+        RuntimeError::ValidatorError(e)
681
+    }
682
+}
683
+
684
+impl Display for ActionError {
685
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
686
+        write!(
687
+            f,
688
+            "Action #{}: {}",
689
+            self.index.unwrap_or_default(),
690
+            self.kind
691
+        )
692
+    }
693
+}
694
+
695
+impl Display for ActionErrorKind {
696
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
697
+        match self {
698
+            ActionErrorKind::AccountAlreadyExists { account_id } => {
699
+                write!(f, "Can't create a new account {:?}, because it already exists", account_id)
700
+            }
701
+            ActionErrorKind::AccountDoesNotExist { account_id } => write!(
702
+                f,
703
+                "Can't complete the action because account {:?} doesn't exist",
704
+                account_id
705
+            ),
706
+            ActionErrorKind::ActorNoPermission { actor_id, account_id } => write!(
707
+                f,
708
+                "Actor {:?} doesn't have permission to account {:?} to complete the action",
709
+                actor_id, account_id
710
+            ),
711
+            ActionErrorKind::LackBalanceForState { account_id, amount } => write!(
712
+                f,
713
+                "The account {} wouldn't have enough balance to cover storage, required to have {} yoctoNEAR more",
714
+                account_id, amount
715
+            ),
716
+            ActionErrorKind::TriesToUnstake { account_id } => {
717
+                write!(f, "Account {:?} is not yet staked, but tries to unstake", account_id)
718
+            }
719
+            ActionErrorKind::TriesToStake { account_id, stake, locked, balance } => write!(
720
+                f,
721
+                "Account {:?} tries to stake {}, but has staked {} and only has {}",
722
+                account_id, stake, locked, balance
723
+            ),
724
+            ActionErrorKind::CreateAccountOnlyByRegistrar { account_id, registrar_account_id, predecessor_id } => write!(
725
+                f,
726
+                "A top-level account ID {:?} can't be created by {:?}, short top-level account IDs can only be created by {:?}",
727
+                account_id, predecessor_id, registrar_account_id,
728
+            ),
729
+            ActionErrorKind::CreateAccountNotAllowed { account_id, predecessor_id } => write!(
730
+                f,
731
+                "A sub-account ID {:?} can't be created by account {:?}",
732
+                account_id, predecessor_id,
733
+            ),
734
+            ActionErrorKind::DeleteKeyDoesNotExist { account_id, .. } => write!(
735
+                f,
736
+                "Account {:?} tries to remove an access key that doesn't exist",
737
+                account_id
738
+            ),
739
+            ActionErrorKind::AddKeyAlreadyExists { public_key, .. } => write!(
740
+                f,
741
+                "The public key {:?} is already used for an existing access key",
742
+                public_key
743
+            ),
744
+            ActionErrorKind::DeleteAccountStaking { account_id } => {
745
+                write!(f, "Account {:?} is staking and can not be deleted", account_id)
746
+            }
747
+            ActionErrorKind::InsufficientStake { account_id, stake, minimum_stake } => write!(f, "Account {} tries to stake {} but minimum required stake is {}", account_id, stake, minimum_stake),
748
+            ActionErrorKind::OnlyImplicitAccountCreationAllowed { account_id } => write!(f, "CreateAccount action is called on hex-characters account of length 64 {}", account_id),
749
+            ActionErrorKind::DeleteAccountWithLargeState { account_id } => write!(f, "The state of account {} is too large and therefore cannot be deleted", account_id),
750
+        }
751
+    }
752
+}
753
+
754
+#[derive(Eq, PartialEq, Clone)]
755
+pub enum EpochError {
756
+    /// Error calculating threshold from given stakes for given number of seats.
757
+    /// Only should happened if calling code doesn't check for integer value of stake > number of seats.
758
+    ThresholdError { stake_sum: Balance, num_seats: u64 },
759
+    /// Missing block hash in the storage (means there is some structural issue).
760
+    MissingBlock(CryptoHash),
761
+    /// Error due to IO (DB read/write, serialization, etc.).
762
+    IOErr(String),
763
+    /// Error getting information for a shard
764
+    ShardingError(String),
765
+    NotEnoughValidators {
766
+        num_validators: u64,
767
+        num_shards: u64,
768
+    },
769
+}
770
+
771
+impl std::error::Error for EpochError {}
772
+
773
+impl Display for EpochError {
774
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
775
+        match self {
776
+            EpochError::ThresholdError {
777
+                stake_sum,
778
+                num_seats,
779
+            } => write!(
780
+                f,
781
+                "Total stake {} must be higher than the number of seats {}",
782
+                stake_sum, num_seats
783
+            ),
784
+            EpochError::MissingBlock(hash) => write!(f, "Missing block {}", hash),
785
+            EpochError::IOErr(err) => write!(f, "IO: {}", err),
786
+            EpochError::ShardingError(err) => write!(f, "Sharding Error: {}", err),
787
+            EpochError::NotEnoughValidators {
788
+                num_shards,
789
+                num_validators,
790
+            } => {
791
+                write!(f, "There were not enough validator proposals to fill all shards. num_proposals: {}, num_shards: {}", num_validators, num_shards)
792
+            }
793
+        }
794
+    }
795
+}
796
+
797
+impl Debug for EpochError {
798
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
799
+        match self {
800
+            EpochError::ThresholdError {
801
+                stake_sum,
802
+                num_seats,
803
+            } => {
804
+                write!(f, "ThresholdError({}, {})", stake_sum, num_seats)
805
+            }
806
+            EpochError::MissingBlock(hash) => write!(f, "MissingBlock({})", hash),
807
+            EpochError::IOErr(err) => write!(f, "IOErr({})", err),
808
+            EpochError::ShardingError(err) => write!(f, "ShardingError({})", err),
809
+            EpochError::NotEnoughValidators {
810
+                num_shards,
811
+                num_validators,
812
+            } => {
813
+                write!(f, "NotEnoughValidators({}, {})", num_validators, num_shards)
814
+            }
815
+        }
816
+    }
817
+}
818
+
819
+impl From<std::io::Error> for EpochError {
820
+    fn from(error: std::io::Error) -> Self {
821
+        EpochError::IOErr(error.to_string())
822
+    }
823
+}

+ 5
- 0
near-primitives-light/src/lib.rs Wyświetl plik

@@ -0,0 +1,5 @@
1
+pub mod errors;
2
+pub mod receipt;
3
+pub mod transaction;
4
+pub mod types;
5
+pub mod views;

+ 179
- 0
near-primitives-light/src/receipt.rs Wyświetl plik

@@ -0,0 +1,179 @@
1
+use borsh::{BorshDeserialize, BorshSerialize};
2
+use near_primitives_core::{
3
+    hash::CryptoHash,
4
+    serialize::{dec_format, option_base64_format, to_base58},
5
+    types::{AccountId, Balance, ShardId},
6
+};
7
+use serde::{Deserialize, Serialize};
8
+use std::{borrow::Borrow, collections::HashMap, fmt, hash::Hash};
9
+
10
+use crate::transaction::*;
11
+use common_api::crypto::prelude::*;
12
+
13
+/// Receipts are used for a cross-shard communication.
14
+/// Receipts could be 2 types (determined by a `ReceiptEnum`): `ReceiptEnum::Action` of `ReceiptEnum::Data`.
15
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
16
+pub struct Receipt {
17
+    /// An issuer account_id of a particular receipt.
18
+    /// `predecessor_id` could be either `Transaction` `signer_id` or intermediate contract's `account_id`.
19
+    pub predecessor_id: AccountId,
20
+    /// `receiver_id` is a receipt destination.
21
+    pub receiver_id: AccountId,
22
+    /// An unique id for the receipt
23
+    pub receipt_id: CryptoHash,
24
+    /// A receipt type
25
+    pub receipt: ReceiptEnum,
26
+}
27
+
28
+impl Borrow<CryptoHash> for Receipt {
29
+    fn borrow(&self) -> &CryptoHash {
30
+        &self.receipt_id
31
+    }
32
+}
33
+
34
+impl Receipt {
35
+    /// It's not a content hash, but receipt_id is unique.
36
+    pub fn get_hash(&self) -> CryptoHash {
37
+        self.receipt_id
38
+    }
39
+
40
+    /// Generates a receipt with a transfer from system for a given balance without a receipt_id.
41
+    /// This should be used for token refunds instead of gas refunds. It doesn't refund the
42
+    /// allowance of the access key. For gas refunds use `new_gas_refund`.
43
+    pub fn new_balance_refund(receiver_id: &AccountId, refund: Balance) -> Self {
44
+        Receipt {
45
+            predecessor_id: "system".parse().unwrap(),
46
+            receiver_id: receiver_id.clone(),
47
+            receipt_id: CryptoHash::default(),
48
+
49
+            receipt: ReceiptEnum::Action(ActionReceipt {
50
+                signer_id: "system".parse().unwrap(),
51
+                signer_public_key: Ed25519PublicKey::try_from_bytes(&[0; 32]).unwrap(),
52
+                gas_price: 0,
53
+                output_data_receivers: vec![],
54
+                input_data_ids: vec![],
55
+                actions: vec![Action::Transfer(TransferAction { deposit: refund })],
56
+            }),
57
+        }
58
+    }
59
+
60
+    /// Generates a receipt with a transfer action from system for a given balance without a
61
+    /// receipt_id. It contains `signer_id` and `signer_public_key` to indicate this is a gas
62
+    /// refund. The execution of this receipt will try to refund the allowance of the
63
+    /// access key with the given public key.
64
+    /// NOTE: The access key may be replaced by the owner, so the execution can't rely that the
65
+    /// access key is the same and it should use best effort for the refund.
66
+    pub fn new_gas_refund(
67
+        receiver_id: &AccountId,
68
+        refund: Balance,
69
+        signer_public_key: Ed25519PublicKey,
70
+    ) -> Self {
71
+        Receipt {
72
+            predecessor_id: "system".parse().unwrap(),
73
+            receiver_id: receiver_id.clone(),
74
+            receipt_id: CryptoHash::default(),
75
+
76
+            receipt: ReceiptEnum::Action(ActionReceipt {
77
+                signer_id: receiver_id.clone(),
78
+                signer_public_key,
79
+                gas_price: 0,
80
+                output_data_receivers: vec![],
81
+                input_data_ids: vec![],
82
+                actions: vec![Action::Transfer(TransferAction { deposit: refund })],
83
+            }),
84
+        }
85
+    }
86
+}
87
+
88
+/// Receipt could be either ActionReceipt or DataReceipt
89
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
90
+#[allow(clippy::large_enum_variant)]
91
+pub enum ReceiptEnum {
92
+    Action(ActionReceipt),
93
+    Data(DataReceipt),
94
+}
95
+
96
+/// ActionReceipt is derived from an Action from `Transaction or from Receipt`
97
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Debug, PartialEq, Eq, Clone)]
98
+pub struct ActionReceipt {
99
+    /// A signer of the original transaction
100
+    pub signer_id: AccountId,
101
+    /// An access key which was used to sign the original transaction
102
+    pub signer_public_key: Ed25519PublicKey,
103
+    /// A gas_price which has been used to buy gas in the original transaction
104
+    #[serde(with = "dec_format")]
105
+    pub gas_price: Balance,
106
+    /// If present, where to route the output data
107
+    pub output_data_receivers: Vec<DataReceiver>,
108
+    /// A list of the input data dependencies for this Receipt to process.
109
+    /// If all `input_data_ids` for this receipt are delivered to the account
110
+    /// that means we have all the `ReceivedData` input which will be than converted to a
111
+    /// `PromiseResult::Successful(value)` or `PromiseResult::Failed`
112
+    /// depending on `ReceivedData` is `Some(_)` or `None`
113
+    pub input_data_ids: Vec<CryptoHash>,
114
+    /// A list of actions to process when all input_data_ids are filled
115
+    pub actions: Vec<Action>,
116
+}
117
+
118
+/// An incoming (ingress) `DataReceipt` which is going to a Receipt's `receiver` input_data_ids
119
+/// Which will be converted to `PromiseResult::Successful(value)` or `PromiseResult::Failed`
120
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Hash, PartialEq, Eq, Clone)]
121
+pub struct DataReceipt {
122
+    pub data_id: CryptoHash,
123
+    #[serde(with = "option_base64_format")]
124
+    pub data: Option<Vec<u8>>,
125
+}
126
+
127
+impl fmt::Debug for DataReceipt {
128
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129
+        f.debug_struct("DataReceipt")
130
+            .field("data_id", &self.data_id)
131
+            .field(
132
+                "data",
133
+                &format_args!("{:?}", self.data.as_deref().map(to_base58)),
134
+            )
135
+            .finish()
136
+    }
137
+}
138
+
139
+/// The outgoing (egress) data which will be transformed
140
+/// to a `DataReceipt` to be sent to a `receipt.receiver`
141
+#[derive(
142
+    BorshSerialize, BorshDeserialize, Serialize, Deserialize, Hash, Clone, Debug, PartialEq, Eq,
143
+)]
144
+pub struct DataReceiver {
145
+    pub data_id: CryptoHash,
146
+    pub receiver_id: AccountId,
147
+}
148
+
149
+/// A temporary data which is created by processing of DataReceipt
150
+/// stored in a state trie with a key = `account_id` + `data_id` until
151
+/// `input_data_ids` of all incoming Receipts are satisfied
152
+/// None means data retrieval was failed
153
+#[derive(BorshSerialize, BorshDeserialize, Hash, PartialEq, Eq, Clone)]
154
+pub struct ReceivedData {
155
+    pub data: Option<Vec<u8>>,
156
+}
157
+
158
+impl fmt::Debug for ReceivedData {
159
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
160
+        f.debug_struct("ReceivedData")
161
+            .field(
162
+                "data",
163
+                &format_args!("{:?}", self.data.as_deref().map(to_base58)),
164
+            )
165
+            .finish()
166
+    }
167
+}
168
+
169
+/// Stores indices for a persistent queue for delayed receipts that didn't fit into a block.
170
+#[derive(Default, BorshSerialize, BorshDeserialize, Clone, PartialEq, Eq, Debug)]
171
+pub struct DelayedReceiptIndices {
172
+    // First inclusive index in the queue.
173
+    pub first_index: u64,
174
+    // Exclusive end index of the queue
175
+    pub next_available_index: u64,
176
+}
177
+
178
+/// Map of shard to list of receipts to send to it.
179
+pub type ReceiptResult = HashMap<ShardId, Vec<Receipt>>;

+ 411
- 0
near-primitives-light/src/transaction.rs Wyświetl plik

@@ -0,0 +1,411 @@
1
+use std::{
2
+    borrow::Borrow,
3
+    fmt,
4
+    hash::{Hash, Hasher},
5
+    str::FromStr,
6
+};
7
+
8
+use borsh::{BorshDeserialize, BorshSerialize};
9
+use common_api::crypto::prelude::*;
10
+use near_primitives_core::{
11
+    account::AccessKey,
12
+    hash::{hash, CryptoHash},
13
+    profile::ProfileData,
14
+    serialize::{base64_format, dec_format, to_base58},
15
+    types::{AccountId, Balance, Gas, Nonce},
16
+};
17
+use serde::{Deserialize, Serialize};
18
+
19
+use crate::errors::TxExecutionError;
20
+
21
+pub type LogEntry = String;
22
+
23
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
24
+pub struct Transaction {
25
+    /// An account on which behalf transaction is signed
26
+    pub signer_id: AccountId,
27
+    /// A public key of the access key which was used to sign an account.
28
+    /// Access key holds permissions for calling certain kinds of actions.
29
+    pub public_key: Ed25519PublicKey,
30
+    /// Nonce is used to determine order of transaction in the pool.
31
+    /// It increments for a combination of `signer_id` and `public_key`
32
+    pub nonce: Nonce,
33
+    /// Receiver account for this transaction
34
+    pub receiver_id: AccountId,
35
+    /// The hash of the block in the blockchain on top of which the given transaction is valid
36
+    pub block_hash: CryptoHash,
37
+    /// A list of actions to be applied
38
+    pub actions: Vec<Action>,
39
+}
40
+
41
+impl Transaction {
42
+    /// Computes a hash of the transaction for signing and size of serialized transaction
43
+    pub fn get_hash_and_size(&self) -> (CryptoHash, u64) {
44
+        let bytes = self.try_to_vec().expect("Failed to deserialize");
45
+        (hash(&bytes), bytes.len() as u64)
46
+    }
47
+}
48
+
49
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Debug, Clone)]
50
+pub enum Action {
51
+    /// Create an (sub)account using a transaction `receiver_id` as an ID for
52
+    /// a new account ID must pass validation rules described here
53
+    /// <http://nomicon.io/Primitives/Account.html>.
54
+    CreateAccount(CreateAccountAction),
55
+    /// Sets a Wasm code to a receiver_id
56
+    DeployContract(DeployContractAction),
57
+    FunctionCall(FunctionCallAction),
58
+    Transfer(TransferAction),
59
+    Stake(StakeAction),
60
+    AddKey(AddKeyAction),
61
+    DeleteKey(DeleteKeyAction),
62
+    DeleteAccount(DeleteAccountAction),
63
+}
64
+
65
+impl Action {
66
+    pub fn get_prepaid_gas(&self) -> Gas {
67
+        match self {
68
+            Action::FunctionCall(a) => a.gas,
69
+            _ => 0,
70
+        }
71
+    }
72
+    pub fn get_deposit_balance(&self) -> Balance {
73
+        match self {
74
+            Action::FunctionCall(a) => a.deposit,
75
+            Action::Transfer(a) => a.deposit,
76
+            _ => 0,
77
+        }
78
+    }
79
+}
80
+
81
+/// Create account action
82
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
83
+pub struct CreateAccountAction {}
84
+
85
+impl From<CreateAccountAction> for Action {
86
+    fn from(create_account_action: CreateAccountAction) -> Self {
87
+        Self::CreateAccount(create_account_action)
88
+    }
89
+}
90
+
91
+/// Deploy contract action
92
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone)]
93
+pub struct DeployContractAction {
94
+    /// WebAssembly binary
95
+    #[serde(with = "base64_format")]
96
+    pub code: Vec<u8>,
97
+}
98
+
99
+impl From<DeployContractAction> for Action {
100
+    fn from(deploy_contract_action: DeployContractAction) -> Self {
101
+        Self::DeployContract(deploy_contract_action)
102
+    }
103
+}
104
+
105
+impl fmt::Debug for DeployContractAction {
106
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
107
+        f.debug_struct("DeployContractAction").finish()
108
+    }
109
+}
110
+
111
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone)]
112
+pub struct FunctionCallAction {
113
+    pub method_name: String,
114
+    #[serde(with = "base64_format")]
115
+    pub args: Vec<u8>,
116
+    pub gas: Gas,
117
+    #[serde(with = "dec_format")]
118
+    pub deposit: Balance,
119
+}
120
+
121
+impl From<FunctionCallAction> for Action {
122
+    fn from(function_call_action: FunctionCallAction) -> Self {
123
+        Self::FunctionCall(function_call_action)
124
+    }
125
+}
126
+
127
+impl fmt::Debug for FunctionCallAction {
128
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
129
+        f.debug_struct("FunctionCallAction")
130
+            .field("method_name", &format_args!("{}", &self.method_name))
131
+            .field("args", &format_args!("{}", to_base58(&self.args)))
132
+            .field("gas", &format_args!("{}", &self.gas))
133
+            .field("deposit", &format_args!("{}", &self.deposit))
134
+            .finish()
135
+    }
136
+}
137
+
138
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
139
+pub struct TransferAction {
140
+    #[serde(with = "dec_format")]
141
+    pub deposit: Balance,
142
+}
143
+
144
+impl From<TransferAction> for Action {
145
+    fn from(transfer_action: TransferAction) -> Self {
146
+        Self::Transfer(transfer_action)
147
+    }
148
+}
149
+
150
+/// An action which stakes signer_id tokens and setup's validator public key
151
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
152
+pub struct StakeAction {
153
+    /// Amount of tokens to stake.
154
+    #[serde(with = "dec_format")]
155
+    pub stake: Balance,
156
+    /// Validator key which will be used to sign transactions on behalf of signer_id
157
+    pub public_key: Ed25519PublicKey,
158
+}
159
+
160
+impl From<StakeAction> for Action {
161
+    fn from(stake_action: StakeAction) -> Self {
162
+        Self::Stake(stake_action)
163
+    }
164
+}
165
+
166
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
167
+pub struct AddKeyAction {
168
+    /// A public key which will be associated with an access_key
169
+    pub public_key: Ed25519PublicKey,
170
+    /// An access key with the permission
171
+    pub access_key: AccessKey,
172
+}
173
+
174
+impl From<AddKeyAction> for Action {
175
+    fn from(add_key_action: AddKeyAction) -> Self {
176
+        Self::AddKey(add_key_action)
177
+    }
178
+}
179
+
180
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
181
+pub struct DeleteKeyAction {
182
+    /// A public key associated with the access_key to be deleted.
183
+    pub public_key: Ed25519PublicKey,
184
+}
185
+
186
+impl From<DeleteKeyAction> for Action {
187
+    fn from(delete_key_action: DeleteKeyAction) -> Self {
188
+        Self::DeleteKey(delete_key_action)
189
+    }
190
+}
191
+
192
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, PartialEq, Eq, Clone, Debug)]
193
+pub struct DeleteAccountAction {
194
+    pub beneficiary_id: AccountId,
195
+}
196
+
197
+impl From<DeleteAccountAction> for Action {
198
+    fn from(delete_account_action: DeleteAccountAction) -> Self {
199
+        Self::DeleteAccount(delete_account_action)
200
+    }
201
+}
202
+
203
+#[derive(BorshSerialize, BorshDeserialize, Serialize, Deserialize, Eq, Debug, Clone)]
204
+#[borsh_init(init)]
205
+pub struct SignedTransaction {
206
+    pub transaction: Transaction,
207
+    pub signature: Ed25519Signature,
208
+    #[borsh_skip]
209
+    hash: CryptoHash,
210
+    #[borsh_skip]
211
+    size: u64,
212
+}
213
+
214
+impl SignedTransaction {
215
+    pub fn new(signature: Ed25519Signature, transaction: Transaction) -> Self {
216
+        let mut signed_tx = Self {
217
+            signature,
218
+            transaction,
219
+            hash: CryptoHash::default(),
220
+            size: u64::default(),
221
+        };
222
+        signed_tx.init();
223
+        signed_tx
224
+    }
225
+
226
+    pub fn init(&mut self) {
227
+        let (hash, size) = self.transaction.get_hash_and_size();
228
+        self.hash = hash;
229
+        self.size = size;
230
+    }
231
+
232
+    pub fn get_hash(&self) -> CryptoHash {
233
+        self.hash
234
+    }
235
+
236
+    pub fn get_size(&self) -> u64 {
237
+        self.size
238
+    }
239
+}
240
+
241
+impl Hash for SignedTransaction {
242
+    fn hash<H: Hasher>(&self, state: &mut H) {
243
+        self.hash.hash(state)
244
+    }
245
+}
246
+
247
+impl PartialEq for SignedTransaction {
248
+    fn eq(&self, other: &SignedTransaction) -> bool {
249
+        self.hash == other.hash && self.signature == other.signature
250
+    }
251
+}
252
+
253
+impl Borrow<CryptoHash> for SignedTransaction {
254
+    fn borrow(&self) -> &CryptoHash {
255
+        &self.hash
256
+    }
257
+}
258
+
259
+/// The status of execution for a transaction or a receipt.
260
+#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
261
+pub enum ExecutionStatus {
262
+    /// The execution is pending or unknown.
263
+    Unknown,
264
+    /// The execution has failed with the given execution error.
265
+    Failure(Box<TxExecutionError>),
266
+    /// The final action succeeded and returned some value or an empty vec.
267
+    SuccessValue(Vec<u8>),
268
+    /// The final action of the receipt returned a promise or the signed transaction was converted
269
+    /// to a receipt. Contains the receipt_id of the generated receipt.
270
+    SuccessReceiptId(CryptoHash),
271
+}
272
+
273
+impl fmt::Debug for ExecutionStatus {
274
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
275
+        match self {
276
+            ExecutionStatus::Unknown => f.write_str("Unknown"),
277
+            ExecutionStatus::Failure(e) => f.write_fmt(format_args!("Failure({})", e)),
278
+            ExecutionStatus::SuccessValue(v) => {
279
+                f.write_fmt(format_args!("SuccessValue({})", to_base58(v)))
280
+            }
281
+            ExecutionStatus::SuccessReceiptId(receipt_id) => {
282
+                f.write_fmt(format_args!("SuccessReceiptId({})", receipt_id))
283
+            }
284
+        }
285
+    }
286
+}
287
+
288
+impl Default for ExecutionStatus {
289
+    fn default() -> Self {
290
+        ExecutionStatus::Unknown
291
+    }
292
+}
293
+
294
+/// ExecutionOutcome for proof. Excludes logs and metadata
295
+#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
296
+pub struct PartialExecutionOutcome {
297
+    pub receipt_ids: Vec<CryptoHash>,
298
+    pub gas_burnt: Gas,
299
+    pub tokens_burnt: Balance,
300
+    pub executor_id: AccountId,
301
+    pub status: PartialExecutionStatus,
302
+}
303
+
304
+impl From<&ExecutionOutcome> for PartialExecutionOutcome {
305
+    fn from(outcome: &ExecutionOutcome) -> Self {
306
+        Self {
307
+            receipt_ids: outcome.receipt_ids.clone(),
308
+            gas_burnt: outcome.gas_burnt,
309
+            tokens_burnt: outcome.tokens_burnt,
310
+            executor_id: outcome.executor_id.clone(),
311
+            status: outcome.status.clone().into(),
312
+        }
313
+    }
314
+}
315
+
316
+/// ExecutionStatus for proof. Excludes failure debug info.
317
+#[derive(BorshSerialize, BorshDeserialize, PartialEq, Eq, Clone)]
318
+pub enum PartialExecutionStatus {
319
+    Unknown,
320
+    Failure,
321
+    SuccessValue(Vec<u8>),
322
+    SuccessReceiptId(CryptoHash),
323
+}
324
+
325
+impl From<ExecutionStatus> for PartialExecutionStatus {
326
+    fn from(status: ExecutionStatus) -> PartialExecutionStatus {
327
+        match status {
328
+            ExecutionStatus::Unknown => PartialExecutionStatus::Unknown,
329
+            ExecutionStatus::Failure(_) => PartialExecutionStatus::Failure,
330
+            ExecutionStatus::SuccessValue(value) => PartialExecutionStatus::SuccessValue(value),
331
+            ExecutionStatus::SuccessReceiptId(id) => PartialExecutionStatus::SuccessReceiptId(id),
332
+        }
333
+    }
334
+}
335
+
336
+/// Execution outcome for one signed transaction or one receipt.
337
+#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Eq)]
338
+pub struct ExecutionOutcome {
339
+    /// Logs from this transaction or receipt.
340
+    pub logs: Vec<LogEntry>,
341
+    /// Receipt IDs generated by this transaction or receipt.
342
+    pub receipt_ids: Vec<CryptoHash>,
343
+    /// The amount of the gas burnt by the given transaction or receipt.
344
+    pub gas_burnt: Gas,
345
+    /// The amount of tokens burnt corresponding to the burnt gas amount.
346
+    /// This value doesn't always equal to the `gas_burnt` multiplied by the gas price, because
347
+    /// the prepaid gas price might be lower than the actual gas price and it creates a deficit.
348
+    pub tokens_burnt: Balance,
349
+    /// The id of the account on which the execution happens. For transaction this is signer_id,
350
+    /// for receipt this is receiver_id.
351
+    pub executor_id: AccountId,
352
+    /// Execution status. Contains the result in case of successful execution.
353
+    /// NOTE: Should be the latest field since it contains unparsable by light client
354
+    /// ExecutionStatus::Failure
355
+    pub status: ExecutionStatus,
356
+    /// Execution metadata, versioned
357
+    pub metadata: ExecutionMetadata,
358
+}
359
+
360
+impl Default for ExecutionOutcome {
361
+    fn default() -> Self {
362
+        Self {
363
+            logs: Default::default(),
364
+            receipt_ids: Default::default(),
365
+            gas_burnt: Default::default(),
366
+            tokens_burnt: Default::default(),
367
+            executor_id: AccountId::from_str("test").unwrap(),
368
+            status: Default::default(),
369
+            metadata: Default::default(),
370
+        }
371
+    }
372
+}
373
+
374
+#[derive(BorshSerialize, BorshDeserialize, PartialEq, Clone, Eq, Debug)]
375
+pub enum ExecutionMetadata {
376
+    // V1: Empty Metadata
377
+    V1,
378
+
379
+    // V2: With ProfileData
380
+    V2(ProfileData),
381
+}
382
+
383
+impl Default for ExecutionMetadata {
384
+    fn default() -> Self {
385
+        ExecutionMetadata::V1
386
+    }
387
+}
388
+
389
+impl fmt::Debug for ExecutionOutcome {
390
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
391
+        f.debug_struct("ExecutionOutcome")
392
+            .field("logs", &self.logs)
393
+            .field("receipt_ids", &self.receipt_ids)
394
+            .field("burnt_gas", &self.gas_burnt)
395
+            .field("tokens_burnt", &self.tokens_burnt)
396
+            .field("status", &self.status)
397
+            .field("metadata", &self.metadata)
398
+            .finish()
399
+    }
400
+}
401
+
402
+/// Execution outcome with the identifier.
403
+/// For a signed transaction, the ID is the hash of the transaction.
404
+/// For a receipt, the ID is the receipt ID.
405
+#[derive(PartialEq, Clone, Default, Debug, BorshSerialize, BorshDeserialize, Eq)]
406
+pub struct ExecutionOutcomeWithId {
407
+    /// The transaction hash or the receipt ID.
408
+    pub id: CryptoHash,
409
+    /// Should be the latest field since contains unparsable by light client ExecutionStatus::Failure
410
+    pub outcome: ExecutionOutcome,
411
+}

+ 236
- 0
near-primitives-light/src/types.rs Wyświetl plik

@@ -0,0 +1,236 @@
1
+use borsh::{BorshDeserialize, BorshSerialize};
2
+use common_api::crypto::prelude::*;
3
+use near_primitives_core::{
4
+    account::{AccessKey, Account},
5
+    hash::CryptoHash,
6
+    serialize::dec_format,
7
+    types::*,
8
+};
9
+use serde::{Deserialize, Serialize};
10
+
11
+/// Hash used by to store state root.
12
+pub type StateRoot = CryptoHash;
13
+
14
+/// Different types of finality.
15
+#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
16
+pub enum Finality {
17
+    #[serde(rename = "optimistic")]
18
+    None,
19
+    #[serde(rename = "near-final")]
20
+    DoomSlug,
21
+    #[serde(rename = "final")]
22
+    Final,
23
+}
24
+
25
+impl Default for Finality {
26
+    fn default() -> Self {
27
+        Finality::Final
28
+    }
29
+}
30
+
31
+#[derive(Debug, Serialize, Deserialize)]
32
+pub struct AccountWithPublicKey {
33
+    pub account_id: AccountId,
34
+    pub public_key: Ed25519PublicKey,
35
+}
36
+
37
+/// Account info for validators
38
+#[derive(Serialize, Deserialize, Clone, Debug, Eq, PartialEq)]
39
+pub struct AccountInfo {
40
+    pub account_id: AccountId,
41
+    pub public_key: Ed25519PublicKey,
42
+    #[serde(with = "dec_format")]
43
+    pub amount: Balance,
44
+}
45
+
46
+/// This type is used to mark function arguments.
47
+///
48
+/// NOTE: The main reason for this to exist (except the type-safety) is that the value is
49
+/// transparently serialized and deserialized as a base64-encoded string when serde is used
50
+/// (serde_json).
51
+#[derive(Debug, Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
52
+pub struct FunctionArgs(Vec<u8>);
53
+
54
+/// A structure used to indicate the kind of state changes due to transaction/receipt processing, etc.
55
+#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
56
+pub enum StateChangeKind {
57
+    AccountTouched { account_id: AccountId },
58
+    AccessKeyTouched { account_id: AccountId },
59
+    DataTouched { account_id: AccountId },
60
+    ContractCodeTouched { account_id: AccountId },
61
+}
62
+
63
+pub type StateChangesKinds = Vec<StateChangeKind>;
64
+
65
+/// A structure used to index state changes due to transaction/receipt processing and other things.
66
+#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
67
+pub enum StateChangeCause {
68
+    /// A type of update that does not get finalized. Used for verification and execution of
69
+    /// immutable smart contract methods. Attempt fo finalize a `TrieUpdate` containing such
70
+    /// change will lead to panic.
71
+    NotWritableToDisk,
72
+    /// A type of update that is used to mark the initial storage update, e.g. during genesis
73
+    /// or in tests setup.
74
+    InitialState,
75
+    /// Processing of a transaction.
76
+    TransactionProcessing { tx_hash: CryptoHash },
77
+    /// Before the receipt is going to be processed, inputs get drained from the state, which
78
+    /// causes state modification.
79
+    ActionReceiptProcessingStarted { receipt_hash: CryptoHash },
80
+    /// Computation of gas reward.
81
+    ActionReceiptGasReward { receipt_hash: CryptoHash },
82
+    /// Processing of a receipt.
83
+    ReceiptProcessing { receipt_hash: CryptoHash },
84
+    /// The given receipt was postponed. This is either a data receipt or an action receipt.
85
+    /// A `DataReceipt` can be postponed if the corresponding `ActionReceipt` is not received yet,
86
+    /// or other data dependencies are not satisfied.
87
+    /// An `ActionReceipt` can be postponed if not all data dependencies are received.
88
+    PostponedReceipt { receipt_hash: CryptoHash },
89
+    /// Updated delayed receipts queue in the state.
90
+    /// We either processed previously delayed receipts or added more receipts to the delayed queue.
91
+    UpdatedDelayedReceipts,
92
+    /// State change that happens when we update validator accounts. Not associated with with any
93
+    /// specific transaction or receipt.
94
+    ValidatorAccountsUpdate,
95
+    /// State change that is happens due to migration that happens in first block of an epoch
96
+    /// after protocol upgrade
97
+    Migration,
98
+    /// State changes for building states for re-sharding
99
+    Resharding,
100
+}
101
+
102
+/// This represents the committed changes in the Trie with a change cause.
103
+#[derive(Debug, Clone, BorshSerialize, BorshDeserialize)]
104
+pub struct RawStateChange {
105
+    pub cause: StateChangeCause,
106
+    pub data: Option<Vec<u8>>,
107
+}
108
+
109
+#[derive(Debug)]
110
+pub enum StateChangesRequest {
111
+    AccountChanges { account_ids: Vec<AccountId> },
112
+    SingleAccessKeyChanges { keys: Vec<AccountWithPublicKey> },
113
+    AllAccessKeyChanges { account_ids: Vec<AccountId> },
114
+    ContractCodeChanges { account_ids: Vec<AccountId> },
115
+}
116
+
117
+#[derive(Debug)]
118
+pub enum StateChangeValue {
119
+    AccountUpdate {
120
+        account_id: AccountId,
121
+        account: Account,
122
+    },
123
+    AccountDeletion {
124
+        account_id: AccountId,
125
+    },
126
+    AccessKeyUpdate {
127
+        account_id: AccountId,
128
+        public_key: Ed25519PublicKey,
129
+        access_key: AccessKey,
130
+    },
131
+    AccessKeyDeletion {
132
+        account_id: AccountId,
133
+        public_key: Ed25519PublicKey,
134
+    },
135
+    ContractCodeUpdate {
136
+        account_id: AccountId,
137
+        code: Vec<u8>,
138
+    },
139
+    ContractCodeDeletion {
140
+        account_id: AccountId,
141
+    },
142
+}
143
+
144
+impl StateChangeValue {
145
+    pub fn affected_account_id(&self) -> &AccountId {
146
+        match &self {
147
+            StateChangeValue::AccountUpdate { account_id, .. }
148
+            | StateChangeValue::AccountDeletion { account_id }
149
+            | StateChangeValue::AccessKeyUpdate { account_id, .. }
150
+            | StateChangeValue::AccessKeyDeletion { account_id, .. }
151
+            | StateChangeValue::ContractCodeUpdate { account_id, .. }
152
+            | StateChangeValue::ContractCodeDeletion { account_id } => account_id,
153
+        }
154
+    }
155
+}
156
+
157
+#[derive(Debug)]
158
+pub struct StateChangeWithCause {
159
+    pub cause: StateChangeCause,
160
+    pub value: StateChangeValue,
161
+}
162
+
163
+pub type StateChanges = Vec<StateChangeWithCause>;
164
+
165
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
166
+#[serde(untagged)]
167
+pub enum BlockId {
168
+    Height(BlockHeight),
169
+    Hash(CryptoHash),
170
+}
171
+
172
+pub type MaybeBlockId = Option<BlockId>;
173
+
174
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
175
+#[serde(rename_all = "snake_case")]
176
+pub enum SyncCheckpoint {
177
+    Genesis,
178
+    EarliestAvailable,
179
+}
180
+
181
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
182
+#[serde(rename_all = "snake_case")]
183
+pub enum BlockReference {
184
+    BlockId(BlockId),
185
+    Finality(Finality),
186
+    SyncCheckpoint(SyncCheckpoint),
187
+}
188
+
189
+impl BlockReference {
190
+    pub fn latest() -> Self {
191
+        Self::Finality(Finality::None)
192
+    }
193
+}
194
+
195
+impl From<BlockId> for BlockReference {
196
+    fn from(block_id: BlockId) -> Self {
197
+        Self::BlockId(block_id)
198
+    }
199
+}
200
+
201
+impl From<Finality> for BlockReference {
202
+    fn from(finality: Finality) -> Self {
203
+        Self::Finality(finality)
204
+    }
205
+}
206
+
207
+#[derive(Default, BorshSerialize, BorshDeserialize, Clone, Debug, PartialEq, Eq)]
208
+pub struct ValidatorStats {
209
+    pub produced: NumBlocks,
210
+    pub expected: NumBlocks,
211
+}
212
+
213
+#[derive(Debug, BorshSerialize, BorshDeserialize, PartialEq, Eq)]
214
+pub struct BlockChunkValidatorStats {
215
+    pub block_stats: ValidatorStats,
216
+    pub chunk_stats: ValidatorStats,
217
+}
218
+
219
+#[derive(Serialize, Deserialize, Clone, Debug)]
220
+#[serde(tag = "type", rename_all = "snake_case")]
221
+pub enum TransactionOrReceiptId {
222
+    Transaction {
223
+        transaction_hash: CryptoHash,
224
+        sender_id: AccountId,
225
+    },
226
+    Receipt {
227
+        receipt_id: CryptoHash,
228
+        receiver_id: AccountId,
229
+    },
230
+}
231
+
232
+#[derive(Debug, Clone, PartialEq, Eq, BorshDeserialize, BorshSerialize)]
233
+pub enum CompiledContract {
234
+    CompileModuleError,
235
+    Code(Vec<u8>),
236
+}

+ 1047
- 0
near-primitives-light/src/views.rs
Plik diff jest za duży
Wyświetl plik


+ 5
- 4
near-rpc/Cargo.toml Wyświetl plik

@@ -13,9 +13,8 @@ bs58 = "0.4"
13 13
 borsh = "0.9"
14 14
 common-api = { path = "../common-api" }
15 15
 itertools = "0.10"
16
-near-account-id = "0.15"
17
-near-primitives = "0.15"
18
-near-crypto = "0.15"
16
+near-primitives-light = { path = "../near-primitives-light" }
17
+near-primitives-core = "0.15"
19 18
 near-units = "0.2"
20 19
 reqwest = { version = "0.11", features = ["json"] }
21 20
 serde = { version = "1", default-features = false, features = ["derive"] }
@@ -30,4 +29,6 @@ rand = "0.8.5"
30 29
 rand_chacha = "0.3"
31 30
 tempfile = "3"
32 31
 tokio = { version = "1.2.1", features = ["full"] }
33
-workspaces = { git = "https://github.com/near/workspaces-rs.git", features = ["unstable"] }
32
+workspaces = { git = "https://github.com/near/workspaces-rs.git", features = [
33
+    "unstable",
34
+] }

+ 10
- 7
near-rpc/src/client.rs Wyświetl plik

@@ -1,19 +1,22 @@
1
-use near_primitives::{
2
-    account::{id::AccountId, AccessKey, AccessKeyPermission},
3
-    hash::CryptoHash,
1
+use near_primitives_light::{
4 2
     transaction::{
5 3
         Action, AddKeyAction, CreateAccountAction, DeleteAccountAction, DeployContractAction,
6 4
         FunctionCallAction, TransferAction,
7 5
     },
8
-    types::{Balance, Finality, Gas, Nonce},
6
+    types::Finality,
9 7
     views::{BlockView, FinalExecutionOutcomeView, FinalExecutionStatus},
10 8
 };
11 9
 
10
+use near_primitives_core::{
11
+    account::{id::AccountId, AccessKey, AccessKeyPermission},
12
+    hash::CryptoHash,
13
+    types::{Balance, Gas, Nonce},
14
+};
15
+
12 16
 use crate::{
13 17
     rpc::client::RpcClient,
14 18
     utils::{
15
-        serialize_arguments, serialize_transaction, to_public_key, TransactionInfo, ViewAccessKey,
16
-        ViewResult,
19
+        serialize_arguments, serialize_transaction, TransactionInfo, ViewAccessKey, ViewResult,
17 20
     },
18 21
     Error, Result,
19 22
 };
@@ -262,7 +265,7 @@ impl NearClient {
262 265
         let actions = vec![
263 266
             CreateAccountAction {}.into(),
264 267
             AddKeyAction {
265
-                public_key: to_public_key(new_account_pk),
268
+                public_key: new_account_pk,
266 269
                 access_key: AccessKey {
267 270
                     nonce: 0,
268 271
                     permission: AccessKeyPermission::FullAccess,

+ 1
- 1
near-rpc/src/lib.rs Wyświetl plik

@@ -12,7 +12,7 @@ pub enum Error {
12 12
     #[error("Transaction not started")]
13 13
     TxNotStarted,
14 14
     #[error("Transaction failed during execution, cause [\"{0:?}\"]")]
15
-    TxExecution(near_primitives::errors::TxExecutionError),
15
+    TxExecution(near_primitives_light::errors::TxExecutionError),
16 16
     #[error("Transaction serialization error: [\"{0}\"]")]
17 17
     TxSerialization(std::io::Error),
18 18
     #[error("Couldn't serialize an argument [\"{0}\"] to view a transaction, cause: [\"{1}\"]")]

+ 16
- 14
near-rpc/src/utils.rs Wyświetl plik

@@ -4,13 +4,15 @@ use crate::{
4 4
     Error, Result,
5 5
 };
6 6
 
7
-use common_api::crypto::prelude::*;
8
-use near_account_id::AccountId;
9
-use near_crypto::{ED25519PublicKey, KeyType, PublicKey, Signature};
10
-use near_primitives::{
7
+// use common_api::crypto::prelude::*;
8
+use near_primitives_core::{
9
+    account::id::AccountId,
11 10
     hash::CryptoHash,
11
+    types::{BlockHeight, Nonce},
12
+};
13
+use near_primitives_light::{
12 14
     transaction::{Action, SignedTransaction, Transaction},
13
-    types::{BlockHeight, Finality, Nonce},
15
+    types::Finality,
14 16
     views::{AccessKeyPermissionView, AccessKeyView},
15 17
 };
16 18
 use serde::{
@@ -87,7 +89,7 @@ pub(crate) async fn serialize_transaction<'a>(
87 89
 
88 90
     let transaction = Transaction {
89 91
         signer_id: info.signer.account().clone(),
90
-        public_key: to_public_key(*info.signer.public_key()),
92
+        public_key: *info.signer.public_key(),
91 93
         nonce: info.signer.nonce() + 1,
92 94
         receiver_id: info.contract_id.clone(),
93 95
         block_hash,
@@ -110,17 +112,17 @@ pub(crate) fn serialize_arguments(args: Option<Value>) -> Result<Vec<u8>> {
110 112
 pub(crate) fn sign_transaction(signer: &Signer, transaction: Transaction) -> SignedTransaction {
111 113
     let (hash, ..) = transaction.get_hash_and_size();
112 114
     let signature = signer.sign(hash.0.as_ref());
113
-    SignedTransaction::new(to_signature(signature), transaction)
115
+    SignedTransaction::new(signature, transaction)
114 116
 }
115 117
 
116
-pub(crate) fn to_public_key(pk: Ed25519PublicKey) -> PublicKey {
117
-    PublicKey::ED25519(ED25519PublicKey(pk.to_bytes()))
118
-}
118
+// pub(crate) fn to_public_key(pk: Ed25519PublicKey) -> PublicKey {
119
+//     PublicKey::ED25519(ED25519PublicKey(pk.to_bytes()))
120
+// }
119 121
 
120
-pub(crate) fn to_signature(signature: Ed25519Signature) -> Signature {
121
-    // Panic is impossible
122
-    Signature::from_parts(KeyType::ED25519, &signature.to_bytes()).unwrap()
123
-}
122
+// pub(crate) fn to_signature(signature: Ed25519Signature) -> Signature {
123
+//     // Panic is impossible
124
+//     Signature::from_parts(KeyType::ED25519, &signature.to_bytes()).unwrap()
125
+// }
124 126
 
125 127
 impl<'de> Deserialize<'de> for ViewAccessKey {
126 128
     fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>

+ 1
- 1
near-rpc/tests/rpc.rs Wyświetl plik

@@ -1,6 +1,6 @@
1 1
 use common_api::crypto::prelude::*;
2 2
 use git2::{Cred, RemoteCallbacks};
3
-use near_primitives::{types::Finality, views::AccessKeyView};
3
+use near_primitives_light::{types::Finality, views::AccessKeyView};
4 4
 use near_rpc::{
5 5
     client::{NearClient, Signer},
6 6
     utils::{ViewAccessKey, ViewAccessKeyResult},

+ 2
- 2
web-client/Cargo.toml Wyświetl plik

@@ -19,8 +19,8 @@ futures = "0.3"
19 19
 gloo-timers = { version = "0.2.4", features = ["futures-core", "futures"] }
20 20
 itertools = "0.10"
21 21
 js-sys = "0.3"
22
-near-account-id = "0.15.0"
23
-near-primitives = "0.15"
22
+near-primitives-light = { path = "../near-primitives-light" }
23
+near-primitives-core = "0.15"
24 24
 near-units = "0.2"
25 25
 near-rpc = { path = "../near-rpc" }
26 26
 rand = { version = "0.8.5" }

+ 1
- 1
web-client/src/errors.rs Wyświetl plik

@@ -1,4 +1,4 @@
1
-use near_account_id::ParseAccountError;
1
+use near_primitives_core::account::id::ParseAccountError;
2 2
 use near_rpc::Error;
3 3
 use wasm_bindgen::convert::{FromWasmAbi, IntoWasmAbi};
4 4
 use wasm_bindgen::prelude::*;

+ 3
- 7
web-client/src/lib.rs Wyświetl plik

@@ -4,16 +4,15 @@ use aes_gcm::{
4 4
 };
5 5
 use futures::{lock::Mutex, select, FutureExt};
6 6
 use itertools::Itertools;
7
-use near_account_id::AccountId;
8 7
 use rand::{RngCore, SeedableRng};
9 8
 use serde_json::json;
10 9
 use wasm_bindgen::prelude::*;
11 10
 
12
-use near_primitives::types::Finality;
11
+use near_primitives_core::{account::id::AccountId, types::Nonce};
12
+use near_primitives_light::types::Finality;
13 13
 use near_rpc::client::{NearClient, Signer};
14 14
 
15 15
 use js_sys::Promise;
16
-use near_primitives::types::Nonce;
17 16
 
18 17
 use std::{ops::DerefMut, str::FromStr, sync::Arc};
19 18
 
@@ -23,10 +22,7 @@ use blake2::{
23 22
 };
24 23
 
25 24
 pub mod errors;
26
-use common_api::crypto::{
27
-    key_exchange::{PublicKey, SecretKey},
28
-    Key as _,
29
-};
25
+use common_api::crypto::prelude::*;
30 26
 
31 27
 use errors::{ApiError, ErrorType};
32 28
 use gloo_timers::future::TimeoutFuture;

+ 2
- 4
web-client/tests/integration.rs Wyświetl plik

@@ -1,8 +1,6 @@
1 1
 use common_api::crypto::prelude::*;
2
-use near_primitives::{
3
-    account::id::AccountId,
4
-    types::{Balance, Finality},
5
-};
2
+use near_primitives_core::{account::id::AccountId, types::Balance};
3
+use near_primitives_light::types::Finality;
6 4
 use near_rpc::client::{NearClient, Signer};
7 5
 use rand::{RngCore, SeedableRng};
8 6
 use rand_chacha::ChaChaRng;

Ładowanie…
Anuluj
Zapisz