Vendor dependencies

This commit is contained in:
2026-08-01 16:11:49 +03:00
parent 7f139a0241
commit 6b5e7f0f8b
29706 changed files with 9575646 additions and 0 deletions
@@ -0,0 +1,418 @@
# `0.10.2` -> `1.0.0` `nearcore` upgrade *migration guide*
The link to `nearcore` pr is [chore: update borsh dependency](https://github.com/near/nearcore/pull/9432)
Steps:
## 1. update dependencies in `nearcore` workspace `Cargo.toml`
First we update to `1.0.0-alpha.5` version, which contains [deprecation](https://github.com/near/borsh-rs/pull/206) of `BorshSerialize::try_to_vec` method.
```diff
diff --git a/Cargo.toml b/Cargo.toml
index f38e88411..1587f4131 100644
--- a/Cargo.toml
+++ b/Cargo.toml
-borsh = { version = "0.10.2", features = ["rc"] }
+borsh = { version = "=1.0.0-alpha.5", features = ["derive", "rc"] }
```
## 2. We receive a great number of deprecation warnings of `borsh::BorshSerialize::try_to_vec` method (`near-primitives-core` and other packages):
```bash
warning: use of deprecated method `borsh::BorshSerialize::try_to_vec`: use `borsh::to_vec(&object)` instead
--> core/primitives-core/src/account.rs:246:25
|
246 | let bytes = acc.try_to_vec().unwrap();
| ^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
```
We choose to fix it at once, as this method is [removed](https://github.com/near/borsh-rs/pull/221) in `1.0.0-alpha.5` -> `1.0.0` transition completely
with following diff:
```diff
diff --git a/core/primitives-core/src/account.rs b/core/primitives-core/src/account.rs
index 50a3a340d..380bf4494 100644
--- a/core/primitives-core/src/account.rs
+++ b/core/primitives-core/src/account.rs
@@ -236,3 +236,2 @@ pub struct FunctionCallPermission {
mod tests {
- use borsh::BorshSerialize;
@@ -245,3 +244,3 @@ mod tests {
let acc = Account::new(1_000_000, 1_000_000, CryptoHash::default(), 100);
- let bytes = acc.try_to_vec().unwrap();
+ let bytes = borsh::to_vec(&acc).unwrap();
assert_eq!(hash(&bytes).to_string(), "EVk5UaxBe8LQ8r8iD5EAxVBs6TJcMDKqyH7PBuho6bBJ");
@@ -257,3 +256,3 @@ mod tests {
};
- let mut old_bytes = &old_account.try_to_vec().unwrap()[..];
+ let mut old_bytes = &borsh::to_vec(&old_account).unwrap()[..];
let new_account = <Account as BorshDeserialize>::deserialize(&mut old_bytes).unwrap();
@@ -264,3 +263,3 @@ mod tests {
assert_eq!(new_account.version, AccountVersion::V1);
- let mut new_bytes = &new_account.try_to_vec().unwrap()[..];
+ let mut new_bytes = &borsh::to_vec(&new_account).unwrap()[..];
let deserialized_account =
...
...
...
```
As `nearcore` has a considerable number of occurencies of usage of `borsh::BorshSerialize::try_to_vec` method,
which are tedious to replace manually, [ast-grep](https://github.com/ast-grep/ast-grep) tool may help to
do the refactoring automatically:
```bash
sg -p '$A.try_to_vec()' -l rs -r 'borsh::to_vec(&$A)' # preview changes
sg -p '$A.try_to_vec()' -l rs -r 'borsh::to_vec(&$A)' -A # apply changes without preview
```
## 3. next we encounter error in `near-primitives` package:
```bash
1 error[E0433]: failed to resolve: could not find `maybestd` in `borsh`
--> core/primitives/src/receipt.rs:1:19 ▐
|
1 | use crate::borsh::maybestd::collections::HashMap;
| ^^^^^^^^ could not find `maybestd` in `borsh`
```
`maybestd` [has moved](https://github.com/near/borsh-rs/pull/171) to a `__private` package in `borsh`, and is not supposed to be
accessed directly now besides from within code, derived in `borsh` traits implementations.
As `near-primitives` crate is not supposed to be used in `no_std` context, we can
replace import with standard collections `HashMap`:
```diff
diff --git a/core/primitives/src/receipt.rs b/core/primitives/src/receipt.rs
index 30af36fb9..d5a6632ed 100644
--- a/core/primitives/src/receipt.rs
+++ b/core/primitives/src/receipt.rs
@@ -1,11 +1,11 @@
-use crate::borsh::maybestd::collections::HashMap;
+use std::collections::HashMap;
```
Otherwise, we would've imported from `hashbrown`:
```diff
-use crate::borsh::maybestd::collections::HashMap;
+#[cfg(feature = "std")]
+use std::collections::HashMap;
+#[cfg(not(feature = "std"))]
+use hashbrown::HashMap;
```
## 4. next we encounter a bunch of similar errors in `near-primitives` with `#[borsh_init(...)]`:
```bash
1 error: cannot find attribute `borsh_init` in this scope ▐
--> core/primitives/src/block_header.rs:267:3 ▐
|
267 | #[borsh_init(init)] ▐
| ^^^^^^^^^^ help: a derive helper attribute with a similar name exists: `borsh_skip`
```
The syntax of this attribute [has changed](https://github.com/near/borsh-rs/pull/187). We change all of these occurencies according to
`#[borsh(init=<initialization_method>)]` syntax. The following diff is shortened to first and last
occurencies:
```diff
diff --git a/core/primitives/src/block_header.rs b/core/primitives/src/block_header.rs
index 38491b52c..84ab48238 100644
--- a/core/primitives/src/block_header.rs
+++ b/core/primitives/src/block_header.rs
@@ -266,3 +266,3 @@ impl ApprovalMessage {
#[derive(BorshSerialize, BorshDeserialize, serde::Serialize, Debug, Clone, Eq, PartialEq)]
-#[borsh_init(init)]
+#[borsh(init=init)]
pub struct BlockHeaderV1 {
...
diff --git a/core/primitives/src/transaction.rs b/core/primitives/src/transaction.rs
index 912120b56..2de7a1d52 100644
--- a/core/primitives/src/transaction.rs
+++ b/core/primitives/src/transaction.rs
@@ -58,3 +58,3 @@ impl Transaction {
)]
-#[borsh_init(init)]
+#[borsh(init=init)]
pub struct SignedTransaction {
```
## 5. next we encounter a large number of similar syntax errors in `near-primitives` package
```bash
1 error: cannot find attribute `borsh_skip` in this scope ▐
--> core/primitives/src/transaction.rs:196:7 ▐
|
196 | #[borsh_skip] ▐
| ^^^^^^^^^^ ▐
```
We change all of these occurencies according to [new](https://github.com/near/borsh-rs/pull/192)
`#[borsh(skip)]` syntax. The following diff is shortened to first and last
occurencies:
```diff
diff --git a/core/primitives/src/block_header.rs b/core/primitives/src/block_header.rs
index 84ab48238..6514f8222 100644
--- a/core/primitives/src/block_header.rs
+++ b/core/primitives/src/block_header.rs
@@ -279,3 +279,3 @@ pub struct BlockHeaderV1 {
/// Cached value of hash for this block.
- #[borsh_skip]
+ #[borsh(skip)]
pub hash: CryptoHash,
...
diff --git a/core/primitives/src/transaction.rs b/core/primitives/src/transaction.rs
index 2de7a1d52..f3ac54ba8 100644
--- a/core/primitives/src/transaction.rs
+++ b/core/primitives/src/transaction.rs
@@ -62,5 +62,5 @@ pub struct SignedTransaction {
pub signature: Signature,
- #[borsh_skip]
+ #[borsh(skip)]
hash: CryptoHash,
- #[borsh_skip]
+ #[borsh(skip)]
size: u64,
...
```
## 6. next we encounter 2 errors in `near-primitives` package similar to those in point 3.:
```bash
1 error[E0433]: failed to resolve: could not find `maybestd` in `borsh`
--> core/primitives/src/action/delegate.rs:119:41
|
119 | fn deserialize_reader<R: borsh::maybestd::io::Read>(
| ^^^^^^^^ could not find `maybestd` in `borsh`
2 error[E0433]: failed to resolve: could not find `maybestd` in `borsh`
--> core/primitives/src/action/delegate.rs:121:50
|
121 | ) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
| ^^^^^^^^ could not find `maybestd` i
n `borsh`
```
As `near-primitives` crate is not supposed to be used in `no_std` context, we can
replace import with `std::io`:
```diff
diff --git a/core/primitives/src/action/delegate.rs b/core/primitives/src/action/delegate.rs
index 25db73022..ebd009a44 100644
--- a/core/primitives/src/action/delegate.rs
+++ b/core/primitives/src/action/delegate.rs
@@ -14,3 +14,3 @@ use near_primitives_core::types::{AccountId, Nonce};
use serde::{Deserialize, Serialize};
-use std::io::{Error, ErrorKind};
+use std::io::{Error, ErrorKind, Read};
@@ -118,5 +118,5 @@ mod private_non_delegate_action {
impl borsh::de::BorshDeserialize for NonDelegateAction {
- fn deserialize_reader<R: borsh::maybestd::io::Read>(
+ fn deserialize_reader<R: Read>(
rd: &mut R,
- ) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
+ ) -> ::core::result::Result<Self, Error> {
match u8::deserialize_reader(rd)? {
```
Otherwise, if we intended to support [both `std` and `no_std`](https://github.com/near/borsh-rs/pull/212), we would've imported from `borsh::io`:
```diff
+use borsh::io::{Error, ErrorKind, Read};
```
## 7. next we encounter an error with `BorshDeserialize` trait derivation:
```bash
1 error[E0277]: the trait bound `&T: borsh::BorshDeserialize` is not satisfied
--> core/primitives/src/signable_message.rs:58:26
|
58 | #[derive(BorshSerialize, BorshDeserialize)]
| ^^^^^^^^^^^^^^^^ the trait `borsh::BorshDeserialize` is not implemented for `&T`
```
on
```rust
/// A wrapper around a message that should be signed using this scheme.
///
/// Only used for constructing a signature, not used to transmit messages. The
/// discriminant prefix is implicit and should be known by the receiver based on
/// the context in which the message is received.
#[derive(BorshSerialize, BorshDeserialize)]
pub struct SignableMessage<'a, T> {
pub discriminant: MessageDiscriminant,
pub msg: &'a T,
}
```
On version change `0.10.3` -> `1.0.0-alpha.5` bounds derivation in `borsh` [has changed](https://github.com/near/borsh-rs/pull/178):
From bounds on the types of the fields:
```rust
impl<'a, T> borsh::de::BorshDeserialize for SignableMessage<'a, T>
where
MessageDiscriminant: borsh::de::BorshDeserialize,
&'a T: borsh::de::BorshDeserialize,
```
to bounds on type parameters, encountered in fields:
```rust
impl<'a, T> borsh::de::BorshDeserialize for SignableMessage<'a, T>
where
T: borsh::de::BorshDeserialize,
```
We could potentially [patch the bounds](https://github.com/near/borsh-rs/pull/180) on struct to make it compile:
```rust
#[derive(BorshSerialize, BorshDeserialize)]
pub struct SignableMessage<'a, T> {
pub discriminant: MessageDiscriminant,
#[borsh(bound(deserialize="&'a T: borsh::de::BorshDeserialize"))]
pub msg: &'a T,
}
```
which would transform into following bound on trait's implementation:
```rust
where
&'a T: borsh::de::BorshDeserialize,
```
But the real issue here is that `borsh` doesn't have a generic implementation
of `BorshDeserialize` for `&'a T`, where `T: borsh::de::BorshDeserialize` (nor did it have it in 0.10.2 version),
and that the derived `BorshDeserialize` wasn't used (and it couldn't be for such a field's type).
So the right change is to remove `BorshDeserialize` derive from the struct:
```diff
diff --git a/core/primitives/src/signable_message.rs b/core/primitives/src/signable_message.rs
index efdd489ac..db97eb1fd 100644
--- a/core/primitives/src/signable_message.rs
+++ b/core/primitives/src/signable_message.rs
@@ -57,3 +57,3 @@ pub struct MessageDiscriminant {
/// the context in which the message is received.
-#[derive(BorshSerialize, BorshDeserialize)]
+#[derive(BorshSerialize)]
pub struct SignableMessage<'a, T> {
```
## 8. next we encounter an error in `near-network` package:
```rust
1 error: You have to specify `#[borsh(use_discriminant=true)]` or `#[borsh(use_discriminant=false)]` for all enums with explicit discriminant
--> chain/network/src/types.rs:56:10
|
56 | pub enum ReasonForBan {
| ^^^^^^^^^^^^
```
```rust
#[derive(borsh::BorshSerialize, borsh::BorshDeserialize, Debug, Clone, PartialEq, Eq, Copy)]
pub enum ReasonForBan {
None = 0,
BadBlock = 1,
BadBlockHeader = 2,
HeightFraud = 3,
BadHandshake = 4,
BadBlockApproval = 5,
Abusive = 6,
InvalidSignature = 7,
InvalidPeerId = 8,
InvalidHash = 9,
InvalidEdge = 10,
InvalidDistanceVector = 11,
Blacklisted = 14,
}
```
We fix it with `#[borsh(use_discriminant=false)]` to preserve the behaviour of borsh before
1.0 release which serialized `ReasonForBan::Blacklisted` as 12 instead of 14
(borsh 0.10 and older [ignored explicit discriminant values in enum definitions](https://github.com/near/borsh-rs/issues/137)):
```diff
diff --git a/chain/network/src/types.rs b/chain/network/src/types.rs
index b2dd97c32..ea2d67f2d 100644
--- a/chain/network/src/types.rs
+++ b/chain/network/src/types.rs
@@ -55,2 +55,3 @@ pub struct KnownProducer {
#[derive(borsh::BorshSerialize, borsh::BorshDeserialize, Debug, Clone, PartialEq, Eq, Copy)]
+#[borsh(use_discriminant=false)]
pub enum ReasonForBan {
```
## 9. change in behaviour, unit test error in ci in `near-primitives` package
Assertion fails:
```rust
#[test]
fn test_delegate_action_deserialization() {
// Expected an error. Buffer is empty
assert_eq!(
NonDelegateAction::try_from_slice(Vec::new().as_ref()).map_err(|e| e.kind()),
Err(ErrorKind::InvalidInput)
);
```
```bash
--- STDERR: near-primitives action::delegate::tests::test_delegate_action_deserialization ---
thread 'action::delegate::tests::test_delegate_action_deserialization' panicked at 'assertion failed: `(left == right)`
left: `Err(InvalidData)`,
right: `Err(InvalidInput)`', core/primitives/src/action/delegate.rs:172:9
```
The `ErrorKind` in error in `borsh` [has changed](https://github.com/near/borsh-rs/pull/170), so we apply the following diff:
```diff
diff --git a/core/primitives/src/action/delegate.rs b/core/primitives/src/action/delegate.rs
index ebd009a44..80a0475b6 100644
--- a/core/primitives/src/action/delegate.rs
+++ b/core/primitives/src/action/delegate.rs
@@ -173,3 +173,3 @@ mod tests {
NonDelegateAction::try_from_slice(Vec::new().as_ref()).map_err(|e| e.kind()),
- Err(ErrorKind::InvalidInput)
+ Err(ErrorKind::InvalidData)
);
```
And there's also a similar error in
```bash
--- STDERR: near-store tests::test_save_to_file ---
thread 'tests::test_save_to_file' panicked at 'assertion failed: `(left == right)`
left: `InvalidInput`,
right: `InvalidData`', core/store/src/lib.rs:1096:9
```
with similar fix.
## 10. errors similar to previous ones, in `near-store`, `near-network` and `near-state-viewer` packages
There was a bunch of `borsh::maybestd` imports, which got replaced by their direct from-`std` counterparts.
## 11. finally, we update `borsh` version to `1.0.0`:
```diff
diff --git a/Cargo.toml b/Cargo.toml
index f38e88411..1587f4131 100644
--- a/Cargo.toml
+++ b/Cargo.toml
-borsh = { version = "=1.0.0-alpha.5", features = ["derive", "rc"] }
+borsh = { version = "1.0.0", features = ["derive", "rc"] }
```
@@ -0,0 +1,587 @@
# `v0.9` -> `v1.0.0` `near-sdk-rs` upgrade *migration guide*
The link to `near-sdk-rs` pr is [chore: borsh version update](https://github.com/near/near-sdk-rs/pull/1075)
Steps:
## 1. update dependencies in `near-sdk/Cargo.toml`.
First we update to `1.0.0-alpha.5` version, which contains [deprecation](https://github.com/near/borsh-rs/pull/206) of `BorshSerialize::try_to_vec` method.
We enable `derive` feature by default, and make `unstable__schema` feature optional, enabled
depending on whether `abi` feature of `near-sdk` package is enabled or not.
```diff
diff --git a/near-sdk/Cargo.toml b/near-sdk/Cargo.toml
index a015a64..e6099d4 100644
--- a/near-sdk/Cargo.toml
+++ b/near-sdk/Cargo.toml
@@ -26,3 +26,3 @@ near-sys = { path = "../near-sys", version = "0.2" }
base64 = "0.13"
-borsh = { version = "0.9", features = ["const-generics"] }
+borsh = { version = "=1.0.0-alpha.5", features = ["derive"] }
bs58 = "0.4"
@@ -35,3 +35,4 @@ once_cell = { version = "1.17", default-features = false }
@@ -58,3 +59,3 @@ unstable = []
legacy = []
-abi = ["near-abi", "schemars", "near-sdk-macros/abi"]
+abi = ["borsh/unstable__schema", "near-abi", "schemars", "near-sdk-macros/abi"]
unit-testing = ["near-vm-logic", "near-primitives-core", "near-primitives", "near-crypto"]
```
## 2. We receive a great number of deprecation warnings of `borsh::BorshSerialize::try_to_vec` method (`near-sdk` package):
```bash
2 warning: use of deprecated method `borsh::BorshSerialize::try_to_vec`: use `borsh::to_vec(&object)` instead
--> near-sdk/src/store/lazy/mod.rs:43:28
|
43 | let serialized = value.try_to_vec().unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));
| ^^^^^^^^^^
|
= note: `#[warn(deprecated)]` on by default
```
We choose to fix it at once, as this method is [removed](https://github.com/near/borsh-rs/pull/221) in `1.0.0-alpha.5` -> `1.0.0` transition completely
with following diff:
```diff
diff --git a/near-sdk/src/store/lazy/mod.rs b/near-sdk/src/store/lazy/mod.rs
index 7df7ee4..42112ea 100644
--- a/near-sdk/src/store/lazy/mod.rs
+++ b/near-sdk/src/store/lazy/mod.rs
@@ -8,3 +8,3 @@ mod impls;
-use borsh::{BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize, to_vec};
use once_cell::unsync::OnceCell;
@@ -42,3 +42,3 @@ where
{
- let serialized = value.try_to_vec().unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));
+ let serialized = to_vec(value).unwrap_or_else(|_| env::panic_str(ERR_VALUE_SERIALIZATION));
env::storage_write(key, &serialized);
...
...
```
where `value` is `&T`, where `T: BorshSerialize`.
## 3. We replace the usage of `BorshSchema::schema_container` method (`near-sdk-macros` package)
To prevent compilation errors in the future, we grep for `schema_container` string.
`schema_container` was changed from being a `BorshSchema` trait method to being a function, external
to the trait in [chore!: make BorshSchema::{add_definition,schema_container} free-standing funcs](https://github.com/near/borsh-rs/pull/204)
We fix code, generated with `near_bindgen` procedural macro, with following diff:
```diff
diff --git a/near-sdk-macros/src/core_impl/abi/abi_generator.rs b/near-sdk-macros/src/core_impl/abi/abi_generator.rs
index cbe659a..994e63c 100644
--- a/near-sdk-macros/src/core_impl/abi/abi_generator.rs
+++ b/near-sdk-macros/src/core_impl/abi/abi_generator.rs
@@ -239,21 +239,21 @@ impl ImplItemMethodInfo {
}
}
}
fn generate_schema(ty: &Type, serializer_type: &SerializerType) -> TokenStream2 {
match serializer_type {
SerializerType::JSON => quote! {
gen.subschema_for::<#ty>()
},
SerializerType::Borsh => quote! {
- <#ty as ::near_sdk::borsh::BorshSchema>::schema_container()
+ ::near_sdk::borsh::schema_container_of::<#ty>()
},
}
}
fn generate_abi_type(ty: &Type, serializer_type: &SerializerType) -> TokenStream2 {
let schema = generate_schema(ty, serializer_type);
match serializer_type {
SerializerType::JSON => quote! {
::near_sdk::__private::AbiType::Json {
type_schema: #schema,
```
## 4. next we encounter error with `#[borsh(use_discriminant=<bool>)]` (`near-sdk` package):
```bash
1 error: You have to specify `#[borsh(use_discriminant=true)]` or `#[borsh(use_discriminant=false)]` for all enums with explicit discriminant
--> near-sdk/src/types/public_key.rs:8:10
|
8 | pub enum CurveType {
| ^^^^^^^^^
```
on
```rust
/// PublicKey curve
#[derive(Debug, Clone, Copy, PartialOrd, Ord, Eq, PartialEq, BorshDeserialize, BorshSerialize)]
#[repr(u8)]
pub enum CurveType {
ED25519 = 0,
SECP256K1 = 1,
}
```
We fix it with `#[borsh(use_discriminant=true)]`, which will behave the same as `#[borsh(use_discriminant=false)]`
in this particular case, where `false` preserves the behaviour of borsh before 1.0 release
(borsh 0.10 and older [ignored explicit discriminant values in enum definitions](https://github.com/near/borsh-rs/issues/137)):
```diff
diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 30ebd43..b539ddd 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -7,2 +7,3 @@ use std::convert::TryFrom;
#[repr(u8)]
+#[borsh(use_discriminant=true)]
pub enum CurveType {
@@ -144,4 +145,4 @@ impl serde::Serialize for PublicKey {
```
## 5. next we encounter errors with `borsh::maybestd` imports (`near-sdk` package):
```bash
1 error[E0432]: unresolved import `borsh::maybestd`
--> near-sdk/src/types/public_key.rs:1:13
|
1 | use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};
| ^^^^^^^^ could not find `maybestd` in `borsh`
2 error[E0432]: unresolved import `borsh::maybestd`
--> near-sdk/src/types/account_id.rs:1:13
|
1 | use borsh::{maybestd::io, BorshDeserialize, BorshSchema, BorshSerialize};
| ^^^^^^^^ could not find `maybestd` in `borsh`
```
```rust
// near-sdk/src/types/public_key.rs
impl BorshDeserialize for PublicKey {
fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
<Vec<u8> as BorshDeserialize>::deserialize(buf).and_then(|s| {
Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
})
}
}
```
`maybestd` [has moved](https://github.com/near/borsh-rs/pull/171) to a `__private` package in `borsh`, and is not supposed to be
accessed directly now besides from within code, derived in `borsh` traits implementations.
As `near-sdk` crate is not supposed to be used in `no_std` context, we can
replace imports with `std::io`:
```diff
diff --git a/near-sdk/src/types/account_id.rs b/near-sdk/src/types/account_id.rs
index a338b5c..7876d77 100644
--- a/near-sdk/src/types/account_id.rs
+++ b/near-sdk/src/types/account_id.rs
@@ -1,5 +1,5 @@
-use borsh::{maybestd::io, BorshDeserialize, BorshSchema, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use serde::{de, Deserialize, Serialize};
use std::convert::TryFrom;
-use std::fmt;
+use std::{fmt, io};
diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 10175a0..4280f70 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -1,4 +1,4 @@
-use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize};
use bs58::decode::Error as B58Error;
-use std::convert::TryFrom;
+use std::{convert::TryFrom, io};
```
Otherwise, if we intended to support [both `std` and `no_std`](https://github.com/near/borsh-rs/pull/212), we would've imported from `borsh::io`:
```diff
-use borsh::{maybestd::io, BorshDeserialize, BorshSerialize};
+use borsh::{BorshDeserialize, BorshSerialize};
+use borsh::io;
```
## 6. next we encounter a large number of similar syntax errors with `borsh_skip` (`near-sdk` package):
```bash
1 error: cannot find attribute `borsh_skip` in this scope
--> near-sdk/src/store/lookup_map/mod.rs:89:7
|
89 | #[borsh_skip]
| ^^^^^^^^^^
```
We change all of these occurencies according to [new](https://github.com/near/borsh-rs/pull/192)
`#[borsh(skip)]` syntax. The following diff is shortened to first and last
occurencies:
```diff
diff --git a/near-sdk/src/collections/lazy_option.rs b/near-sdk/src/collections/lazy_option.rs
index 04e79fb..f4ea0dc 100644
--- a/near-sdk/src/collections/lazy_option.rs
+++ b/near-sdk/src/collections/lazy_option.rs
@@ -19,3 +19,3 @@ pub struct LazyOption<T> {
storage_key: Vec<u8>,
- #[borsh_skip]
+ #[borsh(skip)]
el: PhantomData<T>,
...
diff --git a/near-sdk/src/store/lookup_set/mod.rs b/near-sdk/src/store/lookup_set/mod.rs
index 762956a..b2d1ac0 100644
--- a/near-sdk/src/store/lookup_set/mod.rs
+++ b/near-sdk/src/store/lookup_set/mod.rs
@@ -54,3 +54,3 @@ where
- #[borsh_skip]
+ #[borsh(skip)]
hasher: PhantomData<fn() -> (T, H)>,
```
## 7. next there's a bunch of similar errors with `borsh::maybestd::io` imports (`near-sdk` package):
They're fixed in a similar way as in 5.
## 8. next there's a bunch of similar errors due to `BorshDeserialize` trait signature change (`near-sdk` package):
```bash
1 error[E0046]: not all trait items implemented, missing: `deserialize_reader`
--> near-sdk/src/store/vec/mod.rs:138:1
|
138 | impl<T> BorshDeserialize for Vector<T>
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `deserialize_reader` in implementation
= help: implement the missing item: `fn deserialize_reader<R>(_: &mut R) -> std::result::Result<Self, std::io::Error> where R: std::io::Read { todo!() }
```
The signature of trait has changed on 0.9.3 -> 0.10.0 transition in [implement deserialize_reader](https://github.com/near/borsh-rs/pull/116).
We fix it the following way:
```diff
diff --git a/near-sdk/src/store/free_list/mod.rs b/near-sdk/src/store/free_list/mod.rs
index 43d8908..20a1cc7 100644
--- a/near-sdk/src/store/free_list/mod.rs
+++ b/near-sdk/src/store/free_list/mod.rs
@@ -47,7 +47,7 @@ where
{
- fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+ fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
Ok(Self {
- first_free: BorshDeserialize::deserialize(buf)?,
- occupied_count: BorshDeserialize::deserialize(buf)?,
- elements: BorshDeserialize::deserialize(buf)?,
+ first_free: BorshDeserialize::deserialize_reader(reader)?,
+ occupied_count: BorshDeserialize::deserialize_reader(reader)?,
+ elements: BorshDeserialize::deserialize_reader(reader)?,
})
diff --git a/near-sdk/src/store/unordered_map/mod.rs b/near-sdk/src/store/unordered_map/mod.rs
index 5decc60..d82a8aa 100644
--- a/near-sdk/src/store/unordered_map/mod.rs
+++ b/near-sdk/src/store/unordered_map/mod.rs
@@ -117,6 +117,6 @@ where
{
- fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+ fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
Ok(Self {
- keys: BorshDeserialize::deserialize(buf)?,
- values: BorshDeserialize::deserialize(buf)?,
+ keys: BorshDeserialize::deserialize_reader(reader)?,
+ values: BorshDeserialize::deserialize_reader(reader)?,
})
diff --git a/near-sdk/src/store/vec/mod.rs b/near-sdk/src/store/vec/mod.rs
index 9d19614..94127ba 100644
--- a/near-sdk/src/store/vec/mod.rs
+++ b/near-sdk/src/store/vec/mod.rs
@@ -141,6 +141,6 @@ where
{
- fn deserialize(buf: &mut &[u8]) -> Result<Self, std::io::Error> {
+ fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> Result<Self, std::io::Error> {
Ok(Self {
- len: BorshDeserialize::deserialize(buf)?,
- values: BorshDeserialize::deserialize(buf)?,
+ len: BorshDeserialize::deserialize_reader(reader)?,
+ values: BorshDeserialize::deserialize_reader(reader)?,
})
diff --git a/near-sdk/src/types/account_id.rs b/near-sdk/src/types/account_id.rs
index 7876d77..3da417a 100644
--- a/near-sdk/src/types/account_id.rs
+++ b/near-sdk/src/types/account_id.rs
@@ -88,4 +88,4 @@ impl<'de> Deserialize<'de> for AccountId {
impl BorshDeserialize for AccountId {
- fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
- <String as BorshDeserialize>::deserialize(buf).and_then(|s| {
+ fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
+ <String as BorshDeserialize>::deserialize_reader(reader).and_then(|s| {
Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
diff --git a/near-sdk/src/types/public_key.rs b/near-sdk/src/types/public_key.rs
index 4280f70..b539ddd 100644
--- a/near-sdk/src/types/public_key.rs
+++ b/near-sdk/src/types/public_key.rs
@@ -145,4 +145,4 @@ impl serde::Serialize for PublicKey {
impl BorshDeserialize for PublicKey {
- fn deserialize(buf: &mut &[u8]) -> io::Result<Self> {
- <Vec<u8> as BorshDeserialize>::deserialize(buf).and_then(|s| {
+ fn deserialize_reader<R: io::Read>(reader: &mut R) -> io::Result<Self> {
+ <Vec<u8> as BorshDeserialize>::deserialize_reader(reader).and_then(|s| {
Self::try_from(s).map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
diff --git a/near-sdk/src/collections/unordered_map/mod.rs b/near-sdk/src/collections/unordered_map/mod.rs
index d3ba8d5..aab31a4 100644
--- a/near-sdk/src/collections/unordered_map/mod.rs
+++ b/near-sdk/src/collections/unordered_map/mod.rs
@@ -512,5 +512,5 @@ mod tests {
impl BorshDeserialize for DeserializeCounter {
- fn deserialize(buf: &mut &[u8]) -> std::io::Result<Self> {
+ fn deserialize_reader<R: std::io::Read>(reader: &mut R) -> std::io::Result<Self> {
DES_COUNT.fetch_add(1, Ordering::SeqCst);
- u64::deserialize(buf).map(DeserializeCounter)
+ u64::deserialize_reader(reader).map(DeserializeCounter)
}
```
## 9. next we encounter an error with `BorshDeserialize` trait derivation (`near-sdk` package):
```bash
6 error[E0277]: the trait bound `T: Default` is not satisfied
--> near-sdk/src/store/vec/mod.rs:145:21
|
145 | values: BorshDeserialize::deserialize_reader(reader)?,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `T`
|
note: required for `IndexMap<T>` to implement `BorshDeserialize`
--> near-sdk/src/store/index_map.rs:12:26
|
12 | #[derive(BorshSerialize, BorshDeserialize)]
| ^^^^^^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
13 | pub(crate) struct IndexMap<T>
| ^^^^^^^^^^^
= note: this error originates in the derive macro `BorshDeserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
help: consider further restricting this bound
|
140 | T: BorshSerialize + std::default::Default,
| +++++++++++++++++++++++
```
where `IndexMap<T>` looks like the following:
```rust
#[derive(BorshSerialize, BorshDeserialize)]
pub(crate) struct IndexMap<T>
where
T: BorshSerialize,
{
pub(crate) prefix: Box<[u8]>,
/// Cache for loads and intermediate changes to the underlying index map.
/// The cached entries are wrapped in a [`Box`] to avoid existing pointers from being
/// invalidated.
///
/// Note: u32 indices are used over usize to have consistent functionality across architectures.
/// Some functionality would be different from tests to Wasm if exceeding 32-bit length.
#[borsh(skip)]
pub(crate) cache: StableMap<u32, OnceCell<CacheEntry<T>>>,
}
```
On version change `v0.9` -> `v1.0.0-alpha.5` bounds derivation in `borsh` [has changed](https://github.com/near/borsh-rs/pull/178):
From bounds on the types of the fields:
```rust
// cd near-sdk; cargo expand ::store::index_map
impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
T: BorshSerialize,
Box<[u8]>: borsh::BorshDeserialize,
{
fn deserialize(
buf: &mut &[u8],
) -> ::core::result::Result<Self, borsh::maybestd::io::Error> {
Ok(Self {
prefix: borsh::BorshDeserialize::deserialize(buf)?,
cache: Default::default(),
})
}
}
```
to bounds on type parameters, encountered in fields. `borsh::de::BorshDeserialize` bound
for parameters in non-skipped fields, `core::default::Default` bound - otherwise:
```rust
impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
T: BorshSerialize,
T: core::default::Default,
{
fn deserialize_reader<R: borsh::__private::maybestd::io::Read>(
reader: &mut R,
) -> ::core::result::Result<Self, borsh::__private::maybestd::io::Error> {
Ok(Self {
prefix: borsh::BorshDeserialize::deserialize_reader(reader)?,
cache: core::default::Default::default(),
})
}
}
```
We can instruct `borsh` to [replace automatically derived bound](https://github.com/near/borsh-rs/pull/180) with nothing, as `StableMap` has a `impl<K: Ord, V> Default for StableMap<K, V>`
implementation of its own, as it will be used when deserializing skipped field, irrelevant of bounds on `V`:
```diff
diff --git a/near-sdk/src/store/index_map.rs b/near-sdk/src/store/index_map.rs
index 834fc98..7d1df75 100644
--- a/near-sdk/src/store/index_map.rs
+++ b/near-sdk/src/store/index_map.rs
@@ -23,3 +23,3 @@ where
/// Some functionality would be different from tests to Wasm if exceeding 32-bit length.
- #[borsh(skip)]
+ #[borsh(skip, bound(deserialize = ""))]
pub(crate) cache: StableMap<u32, OnceCell<CacheEntry<T>>>,
```
which would transform into following bound on trait's implementation:
```rust
// line with `T: core::default::Default,` disappeared
impl<T> borsh::de::BorshDeserialize for IndexMap<T>
where
T: BorshSerialize,
{
...
```
Similar diffs were also applied here:
```diff
diff --git a/near-sdk/src/store/lookup_map/mod.rs b/near-sdk/src/store/lookup_map/mod.rs
index 0b20345..927b2d6 100644
--- a/near-sdk/src/store/lookup_map/mod.rs
+++ b/near-sdk/src/store/lookup_map/mod.rs
@@ -88,3 +88,3 @@ where
/// invalidated.
- #[borsh(skip)]
+ #[borsh(skip, bound(deserialize = ""))]
cache: StableMap<K, EntryAndHash<V, H::KeyType>>,
```
```diff
diff --git a/near-sdk/src/store/unordered_set/mod.rs b/near-sdk/src/store/unordered_set/mod.rs
index 4504580..77621b9 100644
--- a/near-sdk/src/store/unordered_set/mod.rs
+++ b/near-sdk/src/store/unordered_set/mod.rs
@@ -83,9 +83,11 @@ pub struct UnorderedSet<T, H = Sha256>
where
T: BorshSerialize + Ord,
H: ToKey,
{
+ #[borsh(bound(serialize = "", deserialize = ""))]
elements: FreeList<T>,
+ #[borsh(bound(serialize = "", deserialize = ""))]
index: LookupMap<T, FreeListIndex, H>,
}
```
## 10. next we encounter an error with `BorshSchema` trait derivation (`near-sdk` package):
```bash
4 error[E0053]: method `add_definitions_recursively` has an incompatible type for trait
--> near-sdk/src/promise.rs:232:22
|
232 | definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected `BTreeMap<String, Definition>`, found `HashMap<String, Definition>`
| help: change the parameter type to match the trait: `&mut BTreeMap<std::string::String, Definition>`
|
= note: expected signature `fn(&mut BTreeMap<std::string::String, Definition>)`
found signature `fn(&mut HashMap<std::string::String, Definition>)`
```
Signature in trait's method [has changed](https://github.com/near/borsh-rs/pull/165/):
```diff
diff --git a/near-sdk/src/promise.rs b/near-sdk/src/promise.rs
index f8afe56..a430568 100644
--- a/near-sdk/src/promise.rs
+++ b/near-sdk/src/promise.rs
@@ -2,3 +2,3 @@ use borsh::BorshSchema;
use std::cell::RefCell;
-use std::collections::HashMap;
+use std::collections::BTreeMap;
use std::io::{Error, Write};
@@ -231,3 +231,3 @@ impl BorshSchema for Promise {
fn add_definitions_recursively(
- definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
+ definitions: &mut BTreeMap<borsh::schema::Declaration, borsh::schema::Definition>,
) {
@@ -576,3 +576,3 @@ where
fn add_definitions_recursively(
- definitions: &mut HashMap<borsh::schema::Declaration, borsh::schema::Definition>,
+ definitions: &mut BTreeMap<borsh::schema::Declaration, borsh::schema::Definition>,
) {
```
## 11. next we encounter an error with both `BorshSerialize` and `BorshDeserialize` traits' derivation (`near-contract-standards` package):
```bash
1 error: proc-macro derive panicked
--> near-contract-standards/src/fungible_token/core_impl.rs:27:10
|
27 | #[derive(BorshDeserialize, BorshSerialize)]
| ^^^^^^^^^^^^^^^^
|
= help: message: called `Result::unwrap()` on an `Err` value: CrateNotFound { crate_name: "borsh", path: "/home/user/Documents/code/near-sdk-rs/near-contract-standards/Cargo.toml" }
2 error: proc-macro derive panicked
--> near-contract-standards/src/fungible_token/core_impl.rs:27:28
|
27 | #[derive(BorshDeserialize, BorshSerialize)]
| ^^^^^^^^^^^^^^
|
= help: message: called `Result::unwrap()` on an `Err` value: CrateNotFound { crate_name: "borsh", path: "/home/user/Documents/code/near-sdk-rs/near-contract-standards/Cargo.toml" }
```
Thing is, `borsh` [has started getting into a `panic`](https://github.com/near/borsh-rs/pull/149) when using [proc-macro-crate](https://crates.io/crates/proc-macro-crate) dependency for derives,
in the cases when `borsh` is not imported as direct dependency in the crate, which attempts to use its derive macros.
`near-contract-standards` wasn't importing `borsh` directly, just using `near-sdk`'s reexports.
We may instruct `BorshSerialize` and `BorshDeserialize` derives to skip this check of direct import
and to [use a reexported version](https://github.com/near/borsh-rs/pull/210) of `borsh` via following diff:
```diff
diff --git a/near-contract-standards/src/fungible_token/core_impl.rs b/near-contract-standards/src/fungible_token/core_impl.rs
index d61ee8e..cae776c 100644
--- a/near-contract-standards/src/fungible_token/core_impl.rs
+++ b/near-contract-standards/src/fungible_token/core_impl.rs
@@ -27,2 +27,3 @@ const ERR_TOTAL_SUPPLY_OVERFLOW: &str = "Total supply overflow";
#[derive(BorshDeserialize, BorshSerialize)]
+#[borsh(crate = "::near_sdk::borsh")]
pub struct FungibleToken {
```
## 12. finally, we update `borsh` version to `1.0.0`:
```diff
diff --git a/near-sdk/Cargo.toml b/near-sdk/Cargo.toml
index a015a64..e6099d4 100644
--- a/near-sdk/Cargo.toml
+++ b/near-sdk/Cargo.toml
@@ -26,3 +26,3 @@ near-sys = { path = "../near-sys", version = "0.2" }
base64 = "0.13"
-borsh = { version = "=1.0.0-alpha.5", features = ["derive"] }
+borsh = { version = "1.0.0", features = ["derive"] }
bs58 = "0.4"
```