Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to view_state() with Complex Types? #256

Open
sinh3ck opened this issue Dec 16, 2022 · 5 comments
Open

How to view_state() with Complex Types? #256

sinh3ck opened this issue Dec 16, 2022 · 5 comments

Comments

@sinh3ck
Copy link

sinh3ck commented Dec 16, 2022

According to the documentation and examples provided in this repo, the way to view the state of the contract is similar to this:

#[derive(BorshDeserialize, BorshSerialize, PanicOnDefault)]
pub struct MyContract {
    pub owner_id: AccountId,
    pub blacklist: UnorderedSet<AccountId>,
}

// ...
// one element was previously inserted in the blacklist

// contract is a deployed Contract instance of MyContract
let state_items = contract.view_state(None).await?;
let state = state_items.get(b"STATE".as_slice()).unwrap();
let contract_state = MyContract::try_from_slice(&state)?;

// The following line works fine
println!("{:?}", contract_state.owner_id);

// The following line works fine -> returns the following
// UnorderedSet { element_index_prefix: [98, 108, 97, 99, 107, 108, 105, 115, 116, 105], elements: Vector { len: 1, prefix: [98, 108, 97, 99, 107, 108, 105, 115, 116, 101] } }
println!("{:?}", contract_state.blacklist);

// The following line panics
println!("{:?}", contract_state.blacklist.to_vec());

Printing the owner_id works just fine. However the last line, when attempting to print a complex type like an UnorderedSet to_vec(), panics with the following message:

thread 'my_test' panicked at 'called `Result::unwrap()` on an `Err` value: HostError(GuestPanic { panic_msg: "The collection is an inconsistent state. Did previous smart contract execution terminate unexpectedly?" })', /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mocked_blockchain.rs:192:78
stack backtrace:
   0: rust_begin_unwind
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/panicking.rs:584:5
   1: core::panicking::panic_fmt
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/panicking.rs:143:14
   2: core::result::unwrap_failed
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/result.rs:1749:5
   3: core::result::Result<T,E>::unwrap
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/result.rs:1065:23
   4: near_sdk::environment::mock::mocked_blockchain::mock_chain::with_mock_interface::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mocked_blockchain.rs:192:49
   5: near_sdk::environment::mock::with_mocked_blockchain::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mod.rs:25:35
   6: std::thread::local::LocalKey<T>::try_with
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:413:16
   7: std::thread::local::LocalKey<T>::with
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:389:9
   8: near_sdk::environment::mock::with_mocked_blockchain
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mod.rs:25:5
   9: near_sdk::environment::mock::mocked_blockchain::mock_chain::with_mock_interface
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mocked_blockchain.rs:192:9
  10: panic_utf8
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/mock/mocked_blockchain.rs:304:9
  11: near_sdk::environment::env::panic_str
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/environment/env.rs:673:14
  12: near_sdk::collections::vector::expect_consistent_state::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:18:27
  13: core::option::Option<T>::unwrap_or_else
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/option.rs:802:21
  14: near_sdk::collections::vector::expect_consistent_state
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:18:5
  15: near_sdk::collections::vector::Vector<T>::get_raw
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:67:14
  16: <near_sdk::collections::vector::RawIter<T> as core::iter::traits::iterator::Iterator>::nth
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:287:9
  17: <near_sdk::collections::vector::Iter<T> as core::iter::traits::iterator::Iterator>::nth
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:336:9
  18: <near_sdk::collections::vector::Iter<T> as core::iter::traits::iterator::Iterator>::next
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/vector.rs:323:9
  19: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter_nested::SpecFromIterNested<T,I>>::from_iter
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/vec/spec_from_iter_nested.rs:26:32
  20: <alloc::vec::Vec<T> as alloc::vec::spec_from_iter::SpecFromIter<T,I>>::from_iter
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/vec/spec_from_iter.rs:33:9
  21: <alloc::vec::Vec<T> as core::iter::traits::collect::FromIterator<T>>::from_iter
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/alloc/src/vec/mod.rs:2552:9
  22: core::iter::traits::iterator::Iterator::collect
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/iter/traits/iterator.rs:1778:9
  23: near_sdk::collections::unordered_set::UnorderedSet<T>::to_vec
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/near-sdk-4.0.0/src/collections/unordered_set.rs:218:9
  24: tests::my_test::{{closure}}
             at ./tests/tests.rs:63:22
  25: <core::future::from_generator::GenFuture<T> as core::future::future::Future>::poll
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/future/mod.rs:84:19
  26: <core::pin::Pin<P> as core::future::future::Future>::poll
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/future/future.rs:123:9
  27: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:525:48
  28: tokio::coop::with_budget::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/coop.rs:102:9
  29: std::thread::local::LocalKey<T>::try_with
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:413:16
  30: std::thread::local::LocalKey<T>::with
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/std/src/thread/local.rs:389:9
  31: tokio::coop::with_budget
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/coop.rs:95:5
  32: tokio::coop::budget
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/coop.rs:72:5
  33: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:525:25
  34: tokio::runtime::scheduler::current_thread::Context::enter
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:349:19
  35: tokio::runtime::scheduler::current_thread::CoreGuard::block_on::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:524:36
  36: tokio::runtime::scheduler::current_thread::CoreGuard::enter::{{closure}}
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:595:57
  37: tokio::macros::scoped_tls::ScopedKey<T>::set
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/macros/scoped_tls.rs:61:9
  38: tokio::runtime::scheduler::current_thread::CoreGuard::enter
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:595:27
  39: tokio::runtime::scheduler::current_thread::CoreGuard::block_on
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:515:19
  40: tokio::runtime::scheduler::current_thread::CurrentThread::block_on
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/scheduler/current_thread.rs:161:24
  41: tokio::runtime::Runtime::block_on
             at /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/tokio-1.21.1/src/runtime/mod.rs:490:46
  42: tests::my_test
             at ./tests/tests.rs:74:5
  43: tests::my_test::{{closure}}
             at ./tests/tests.rs:19:7
  44: core::ops::function::FnOnce::call_once
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ops/function.rs:227:5
  45: core::ops::function::FnOnce::call_once
             at /rustc/7737e0b5c4103216d6fd8cf941b7ab9bdbaace7c/library/core/src/ops/function.rs:227:5

I have also tried the following, but it also panics with the same message:

println!("{:?}", contract_state.blacklist.as_vector().get(0));

From what I gather, the panic is occurring on line 15 of the backtrace near_sdk::collections::vector::Vector<T>::get_raw when the call to storage_read() with the correct lookup_key is returning None.

What's the correct way of printing this UnorderedSet's elements?
If there's a way, could you include it on one of the examples in this repo?

Thanks in advance.

@sinh3ck sinh3ck changed the title How to View Complex Types on State? How to view_state() with Complex Types? Dec 16, 2022
@sinh3ck sinh3ck changed the title How to view_state() with Complex Types? How to view_state() with Complex Types? Dec 16, 2022
@sinh3ck
Copy link
Author

sinh3ck commented Dec 17, 2022

What I ended up doing was grabbing the elements of the blacklist (which are present in blackliste), iterating through them and inserting them on a new HashSet. I don't believe this is the correct approach but it serves for now.

Does anyone know of a better approach?

let state_items = contract.view_state(None).await?;
let state = state_items.get(b"STATE".as_slice()).unwrap();
let contract_state = MyContract::try_from_slice(&state)?;

let state_items = contract.view_state(Some(b"blacklist")).await?;
let mut blacklist_state: HashSet<AccountId> = HashSet::new();
for val in 0..contract_state.blacklist.len() {     // len() works
    let state = state_items.get(&[b"blackliste".as_slice(), &val.to_le_bytes()].concat()).unwrap();
    blacklist_state.insert(AccountId::try_from_slice(&state).unwrap());
}
println!("{:#?}", blacklist_state.clone());

// can use blacklist_state.contains() now

@ChaoticTempest
Copy link
Member

@sinh3ck I think this is because you need to enable the expensive-debug feature flag in your near-sdk dependency. This is because formatting code mechanisms are expensive which is why println!("{:?}", contract_state.blacklist) shows a bunch of bytes for your unordered set

@sinh3ck
Copy link
Author

sinh3ck commented Dec 18, 2022

@ChaoticTempest Thanks for your input. I noticed that on the UnorderedSet docs, but printing was not enough for me. Functions like, to_vec(), remove(), and contains() is what I'm interested. None of them work properly. The only one that somehow managed to work was len().

@ChaoticTempest
Copy link
Member

@sinh3ck sorry, I thought I commented on this a while back, but calling methods like to_vec() in workspaces-side won't get what you want. In fact, you shouldn't rely fully on methods defined in near-sdk as they only work while in the NEAR chain environment (since it relies on storage APIs). For instance, to_vec is pulling data from the chain's storage when it tries to convert itself into Vec. To actually read the state for each element is a much more manual process, and currently is not automated inside workspaces.

If you still want to continue with viewing these collection types, you'll have to grab the prefix from UnorderedSet, and do worker.view_state on each element. Viewing the actual data from from near_sdk::collections is complicated, but let me bring it up to people and see if this is a pain point we can automate away

@sinh3ck
Copy link
Author

sinh3ck commented Jan 6, 2023

@ChaoticTempest I'm glad I brought this up then. I guess it's more like a feature request now. It would be nice to grab the state and view the data in a more automated fashion. Even considering that simple types can be grabbed right away, while the big problem is with collections and nested collections.

Thanks for your help!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants