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

chore: Add view_account, view_code, view_block #82

Merged
merged 9 commits into from
Mar 4, 2022
2 changes: 1 addition & 1 deletion workspaces/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ mod worker;

pub mod prelude;

pub use network::{Account, Contract, DevNetwork, Network};
pub use network::{Account, AccountDetails, Block, Contract, DevNetwork, Network};
pub use types::{AccountId, BlockHeight, CryptoHash, InMemorySigner};
pub use worker::{
mainnet, mainnet_archival, sandbox, testnet, with_mainnet, with_sandbox, with_testnet, Worker,
Expand Down
46 changes: 45 additions & 1 deletion workspaces/src/network/account.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use std::convert::TryInto;

use near_crypto::KeyType;
use near_primitives::views::AccountView;

use crate::rpc::client::{DEFAULT_CALL_DEPOSIT, DEFAULT_CALL_FN_GAS};
use crate::types::{AccountId, Balance, Gas, InMemorySigner, SecretKey};
use crate::{Network, Worker};
use crate::{CryptoHash, Network, Worker};

use super::{CallExecution, CallExecutionDetails, ViewResultDetails};

Expand Down Expand Up @@ -75,6 +76,14 @@ impl Account {
.await
}

/// Views the current account's details such as balance and storage usage.
pub async fn view_account<T: Network>(
&self,
worker: &Worker<T>,
) -> anyhow::Result<AccountDetails> {
worker.view_account(&self.id).await
}

/// Create a new sub account. Returns a CreateAccountBuilder object that
/// we can make use of to fill out the rest of the details. The sub account
/// id will be in the form of: "{new_account_id}.{parent_account_id}"
Expand Down Expand Up @@ -165,6 +174,19 @@ impl Contract {
worker.view(self.id(), function, args).await
}

/// View the WASM code bytes of this contract.
pub async fn view_code<T: Network>(&self, worker: &Worker<T>) -> anyhow::Result<Vec<u8>> {
worker.view_code(self.id()).await
}

/// Views the current contract's details such as balance and storage usage.
pub async fn view_account<T: Network>(
&self,
worker: &Worker<T>,
) -> anyhow::Result<AccountDetails> {
worker.view_account(self.id()).await
}

/// Deletes the current contract, and returns the execution details of this
/// transaction. The beneciary will receive the funds of the account deleted
pub async fn delete_contract<T: Network>(
Expand Down Expand Up @@ -314,3 +336,25 @@ where
})
}
}

/// Details of an Account or Contract. This is an non-exhaustive list of items
/// that the account stores in the blockchain state.
#[derive(Debug, PartialEq)]
#[non_exhaustive]
pub struct AccountDetails {
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved
pub balance: Balance,
pub locked: Balance,
pub code_hash: CryptoHash,
pub storage_usage: u64,
}

impl From<AccountView> for AccountDetails {
fn from(account: AccountView) -> Self {
Self {
balance: account.amount,
locked: account.locked,
code_hash: CryptoHash(account.code_hash.0),
storage_usage: account.storage_usage,
}
}
}
60 changes: 60 additions & 0 deletions workspaces/src/network/block.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
use near_primitives::views::{BlockHeaderView, BlockView};

use crate::{BlockHeight, CryptoHash};

/// Struct containing information on block coming from the network
#[derive(Debug, PartialEq)]
pub struct Block {
header: BlockHeader,
}

impl Block {
/// The block timestamp in nanoseconds.
pub fn timestamp(&self) -> u64 {
self.header.timestamp_nanosec
}

/// Current height of this block.
pub fn height(&self) -> BlockHeight {
self.header.height
}

/// The hash of the block itself.
pub fn hash(&self) -> &CryptoHash {
&self.header.hash
}

/// The id of an epoch this block belongs to.
pub fn epoch_id(&self) -> &CryptoHash {
&self.header.epoch_id
}
}

/// The block header info. This is a non-exhaustive list of items that
/// could be present in a block header. More can be added in the future.
#[derive(Debug, PartialEq)]
struct BlockHeader {
height: BlockHeight,
epoch_id: CryptoHash,
hash: CryptoHash,
timestamp_nanosec: u64,
}
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved

impl From<BlockView> for Block {
fn from(block_view: BlockView) -> Self {
Self {
header: block_view.header.into(),
}
}
}

impl From<BlockHeaderView> for BlockHeader {
fn from(header_view: BlockHeaderView) -> Self {
Self {
height: header_view.height,
epoch_id: CryptoHash(header_view.epoch_id.0),
hash: CryptoHash(header_view.hash.0),
timestamp_nanosec: header_view.timestamp_nanosec,
}
}
}
4 changes: 3 additions & 1 deletion workspaces/src/network/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
mod account;
mod block;
mod info;
mod mainnet;
mod result;
Expand All @@ -17,7 +18,8 @@ use crate::rpc::patch::ImportContractBuilder;
use crate::types::{AccountId, KeyType, SecretKey};
use crate::Worker;

pub use crate::network::account::{Account, Contract};
pub use crate::network::account::{Account, AccountDetails, Contract};
pub use crate::network::block::Block;
pub use crate::network::mainnet::Mainnet;
pub use crate::network::result::{CallExecution, CallExecutionDetails, ViewResultDetails};
pub use crate::network::sandbox::Sandbox;
Expand Down
15 changes: 14 additions & 1 deletion workspaces/src/rpc/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ use near_primitives::transaction::{
};
use near_primitives::types::{Balance, BlockId, Finality, Gas, StoreKey};
use near_primitives::views::{
AccessKeyView, AccountView, ContractCodeView, FinalExecutionOutcomeView, QueryRequest,
AccessKeyView, AccountView, BlockView, ContractCodeView, FinalExecutionOutcomeView,
QueryRequest,
};

use crate::network::ViewResultDetails;
Expand Down Expand Up @@ -238,6 +239,18 @@ impl Client {
}
}

pub(crate) async fn view_block(&self, block_id: Option<BlockId>) -> anyhow::Result<BlockView> {
let block_reference = block_id
.map(Into::into)
.unwrap_or_else(|| Finality::None.into());

let block_view = self
.query(&methods::block::RpcBlockRequest { block_reference })
.await?;

Ok(block_view)
}

pub(crate) async fn deploy(
&self,
signer: &InMemorySigner,
Expand Down
17 changes: 16 additions & 1 deletion workspaces/src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
/// and internal libraries like near-jsonrpc-client requires specific versions
/// of these types which shouldn't be exposed either.
use std::convert::TryFrom;
use std::fmt;
use std::path::Path;

pub use near_account_id::AccountId;
pub(crate) use near_crypto::{KeyType, Signer};
use near_primitives::serialize::from_base;
use near_primitives::logging::pretty_hash;
use near_primitives::serialize::{from_base, to_base};
use serde::{Deserialize, Serialize};

pub type Gas = u64;
Expand Down Expand Up @@ -62,6 +64,7 @@ impl InMemorySigner {

// type taken from near_primitives::hash::CryptoHash.
/// CryptoHash is type for storing the hash of a specific block.
#[derive(PartialEq)]
pub struct CryptoHash(pub [u8; 32]);

impl std::str::FromStr for CryptoHash {
Expand Down Expand Up @@ -93,3 +96,15 @@ impl TryFrom<Vec<u8>> for CryptoHash {
<Self as TryFrom<&[u8]>>::try_from(v.as_ref())
}
}

impl fmt::Debug for CryptoHash {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

impl std::hash::Hash seems like a reasonable addition.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you can use it as keys to HashMap & HashSet

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, could derive it, probably worth adding

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you can use it as keys to HashMap & HashSet

oops had deleted my comment and updated it before I saw you responded. Sorry for my brain lapse :D

fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", pretty_hash(&self.to_string()))
}
}

impl fmt::Display for CryptoHash {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
fmt::Display::fmt(&to_base(&self.0), f)
}
}
34 changes: 31 additions & 3 deletions workspaces/src/worker/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,15 @@ use async_trait::async_trait;
use near_primitives::types::{Balance, StoreKey};

use crate::network::{
Account, AllowDevAccountCreation, CallExecution, CallExecutionDetails, Contract, NetworkClient,
NetworkInfo, StatePatcher, TopLevelAccountCreator, ViewResultDetails,
Account, AllowDevAccountCreation, Block, CallExecution, CallExecutionDetails, Contract,
NetworkClient, NetworkInfo, StatePatcher, TopLevelAccountCreator, ViewResultDetails,
};
use crate::network::{Info, Sandbox};
use crate::rpc::client::{Client, DEFAULT_CALL_DEPOSIT, DEFAULT_CALL_FN_GAS};
use crate::rpc::patch::ImportContractBuilder;
use crate::types::{AccountId, Gas, InMemorySigner, SecretKey};
use crate::worker::Worker;
use crate::Network;
use crate::{AccountDetails, Network};

impl<T> Clone for Worker<T> {
fn clone(&self) -> Self {
Expand Down Expand Up @@ -87,6 +87,7 @@ where
self.workspace.client()
}

/// Call into a contract's change function.
pub async fn call(
&self,
contract: &Contract,
Expand All @@ -108,6 +109,7 @@ where
.and_then(CallExecutionDetails::from_outcome)
}

/// Call into a contract's view function.
pub async fn view(
&self,
contract_id: &AccountId,
Expand All @@ -119,6 +121,15 @@ where
.await
}

/// View the WASM code bytes of a contract on the network.
pub async fn view_code(&self, contract_id: &AccountId) -> anyhow::Result<Vec<u8>> {
let code_view = self.client().view_code(contract_id.clone(), None).await?;
Ok(code_view.code)
}

/// View the state of a account/contract on the network. This will return the internal
/// state of the account in the form of a map of key-value pairs; where STATE contains
/// info on a contract's internal data.
pub async fn view_state(
&self,
contract_id: &AccountId,
Expand All @@ -127,6 +138,13 @@ where
self.client().view_state(contract_id.clone(), prefix).await
}

/// View the latest block from the network
pub async fn view_latest_block(&self) -> anyhow::Result<Block> {
self.client().view_block(None).await.map(Into::into)
}
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved

/// Transfer tokens from one account to another. The signer is the account
/// that will be used to to send from.
pub async fn transfer_near(
&self,
signer: &InMemorySigner,
Expand All @@ -139,6 +157,8 @@ where
.and_then(CallExecutionDetails::from_outcome)
}

/// Deletes an account from the network. The beneficiary will receive the balance
/// of the account deleted.
pub async fn delete_account(
&self,
account_id: &AccountId,
Expand All @@ -150,6 +170,14 @@ where
.await
.and_then(CallExecutionDetails::from_outcome)
}

/// View account details of a specific account on the network.
pub async fn view_account(&self, account_id: &AccountId) -> anyhow::Result<AccountDetails> {
self.client()
.view_account(account_id.clone(), None)
.await
.map(Into::into)
}
ChaoticTempest marked this conversation as resolved.
Show resolved Hide resolved
}

impl Worker<Sandbox> {
Expand Down