diff --git a/examples/Cargo.toml b/examples/Cargo.toml index 992d54ea..76a302a7 100644 --- a/examples/Cargo.toml +++ b/examples/Cargo.toml @@ -10,8 +10,6 @@ borsh = "1.2.0" maplit = "1.0" near-units = "0.2.0" near-gas = { version = "0.2.3", features = ["serde", "borsh", "schemars"] } -near-jsonrpc-primitives = "0.17" -near-primitives = "0.17" serde = "1.0" serde_with = "3.4" serde_json = { version = "1.0" } diff --git a/examples/src/changes.rs b/examples/src/changes.rs index 247013ac..957cf10f 100644 --- a/examples/src/changes.rs +++ b/examples/src/changes.rs @@ -1,4 +1,3 @@ -use near_primitives::{types::BlockReference, views::StateChangesRequestView}; use serde_json::json; const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm"; @@ -9,27 +8,17 @@ async fn main() -> anyhow::Result<()> { let wasm = std::fs::read(STATUS_MSG_WASM_FILEPATH)?; let contract = worker.dev_deploy(&wasm).await?; - let outcome = contract + _ = contract .call("set_status") .args_json(json!({ "message": "hello_world", })) .transact() - .await?; - - let block_ref = { - let hash = near_primitives::hash::CryptoHash(outcome.outcome().block_hash.0); - BlockReference::BlockId(near_primitives::types::BlockId::Hash(hash)) - }; - - let state_changes = { - StateChangesRequestView::ContractCodeChanges { - account_ids: vec![contract.id().clone()], - } - }; + .await? + .into_result()?; // NOTE: this API is under the "experimental" flag and no guarantees are given. - let res = worker.changes(block_ref, state_changes).await?; + let res = worker.changes(&[contract.id().clone()]).await?; // Example output: // diff --git a/examples/src/changes_in_block.rs b/examples/src/changes_in_block.rs index d026b8f5..c47465ba 100644 --- a/examples/src/changes_in_block.rs +++ b/examples/src/changes_in_block.rs @@ -1,4 +1,3 @@ -use near_primitives::types::BlockReference; use serde_json::json; const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm"; @@ -9,40 +8,26 @@ async fn main() -> anyhow::Result<()> { let wasm = std::fs::read(STATUS_MSG_WASM_FILEPATH)?; let contract = worker.dev_deploy(&wasm).await?; - let outcome = contract + _ = contract .call("set_status") .args_json(json!({ "message": "hello_world", })) .transact() - .await?; - - let block_ref = { - let hash = near_primitives::hash::CryptoHash(outcome.outcome().block_hash.0); - BlockReference::BlockId(near_primitives::types::BlockId::Hash(hash)) - }; + .await? + .into_result()?; // NOTE: this API is under the "experimental" flag and no guarantees are given. - let res = worker.changes_in_block(block_ref).await?; + let res = worker.changes_in_block().await?; // Example output: // // StateChangesInBlockByType RpcStateChangesInBlockByTypeResponse { - // block_hash: 7ifRdyBsJMXVyp8zw8uGdBMaRShiXuD6yghrp66jqrst, + // block_hash: CixdibXkD1ifLmmVXNhEiRGRH6eB9171Q2UhCP2NazJz, // changes: [ // AccountTouched { // account_id: AccountId( - // "dev-20230822100117-44171728969098", - // ), - // }, - // AccessKeyTouched { - // account_id: AccountId( - // "dev-20230822100117-44171728969098", - // ), - // }, - // DataTouched { - // account_id: AccountId( - // "dev-20230822100117-44171728969098", + // "dev-20230913102437-62490697138398", // ), // }, // ], diff --git a/examples/src/protocol_config.rs b/examples/src/protocol_config.rs index 785c9ce9..77da8e33 100644 --- a/examples/src/protocol_config.rs +++ b/examples/src/protocol_config.rs @@ -1,28 +1,9 @@ -const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm"; - #[tokio::main] async fn main() -> anyhow::Result<()> { let worker = near_workspaces::sandbox().await?; - let wasm = std::fs::read(STATUS_MSG_WASM_FILEPATH)?; - let contract = worker.dev_deploy(&wasm).await?; - - let outcome = contract - .call("set_status") - .args_json(serde_json::json!({ - "message": "hello_world", - })) - .transact() - .await?; - - let block_reference = { - let hash = outcome.outcome().block_hash; - near_primitives::types::BlockReference::BlockId(near_primitives::types::BlockId::Hash( - near_primitives::hash::CryptoHash(hash.0), - )) - }; // NOTE: this API is under the "experimental" flag and no guarantees are given. - let protocol_config = worker.protocol_config(block_reference).await?; + let protocol_config = worker.protocol_config().await?; // Example output: // diff --git a/examples/src/receipt.rs b/examples/src/receipt.rs index 450fb872..8df3ad4b 100644 --- a/examples/src/receipt.rs +++ b/examples/src/receipt.rs @@ -1,5 +1,3 @@ -use near_jsonrpc_primitives::types::receipts::ReceiptReference; - const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm"; #[tokio::main] @@ -16,24 +14,14 @@ async fn main() -> anyhow::Result<()> { .transact() .await?; - let receipt_ref = { - let mut ids = outcome.outcome().receipt_ids.clone(); - if ids.is_empty() { - println!("no receipt ids present"); - return Ok(()); - } - - println!("receipts found: {ids:?}"); - - ReceiptReference { - receipt_id: near_primitives::hash::CryptoHash( - ids.pop().expect("expected at least one receipt id").0, - ), - } - }; + // let receipt_ref = receipt(&outcome.outcome().receipt_ids)?; + let ids = &outcome.outcome().receipt_ids; + println!("receipts found: {ids:?}"); // NOTE: this API is under the "experimental" flag and no guarantees are given. - let resp = worker.receipt(receipt_ref).await?; + let resp = worker + .receipt(ids.last().expect("a receipt id is expected")) + .await?; println!("ReceiptView: {resp:?}"); Ok(()) diff --git a/examples/src/tx_status.rs b/examples/src/tx_status.rs index ace5791d..12d8621a 100644 --- a/examples/src/tx_status.rs +++ b/examples/src/tx_status.rs @@ -1,5 +1,3 @@ -use near_jsonrpc_primitives::types::transactions::TransactionInfo; -use near_primitives::hash::CryptoHash; use serde_json::json; const STATUS_MSG_WASM_FILEPATH: &str = "./examples/res/status_message.wasm"; @@ -18,16 +16,12 @@ async fn main() -> anyhow::Result<()> { .transact() .await?; - let tx_info = { - let outcome = outcome.outcome(); - TransactionInfo::TransactionId { - hash: CryptoHash(outcome.transaction_hash.0), - account_id: outcome.executor_id.clone(), - } - }; + let outcome = outcome.outcome(); // NOTE: this API is under the "experimental" flag and no guarantees are given. - let resp = worker.tx_status(tx_info).await?; + let resp = worker + .tx_status(outcome.transaction_hash, outcome.executor_id.clone()) + .await?; // Example outcome: // diff --git a/workspaces/src/rpc/client.rs b/workspaces/src/rpc/client.rs index 50d978de..d04e6f9a 100644 --- a/workspaces/src/rpc/client.rs +++ b/workspaces/src/rpc/client.rs @@ -28,16 +28,13 @@ use near_primitives::views::{ #[cfg(feature = "experimental")] use { - near_chain_configs::{GenesisConfig, ProtocolConfigView}, - near_jsonrpc_primitives::types::{ - changes::RpcStateChangesInBlockByTypeResponse, changes::RpcStateChangesInBlockResponse, - receipts::ReceiptReference, transactions::TransactionInfo, - }, + near_chain_configs::GenesisConfig, + near_jsonrpc_primitives::types::{receipts::ReceiptReference, transactions::TransactionInfo}, near_primitives::{ types::MaybeBlockId, views::{ validator_stake_view::ValidatorStakeView, FinalExecutionOutcomeWithReceiptView, - ReceiptView, StateChangesRequestView, + ReceiptView, }, }, }; @@ -356,41 +353,6 @@ impl Client { #[cfg(feature = "experimental")] impl Client { - pub(crate) async fn changes_in_block( - &self, - block_reference: BlockReference, - ) -> Result { - let resp = self - .rpc_client - .call( - methods::EXPERIMENTAL_changes_in_block::RpcStateChangesInBlockRequest { - block_reference, - }, - ) - .await - .map_err(|e| RpcErrorCode::QueryFailure.custom(e))?; - - Ok(resp) - } - - pub(crate) async fn changes( - &self, - block_reference: BlockReference, - state_changes_request: StateChangesRequestView, - ) -> Result { - let resp = self - .rpc_client - .call( - methods::EXPERIMENTAL_changes::RpcStateChangesInBlockByTypeRequest { - block_reference, - state_changes_request, - }, - ) - .await - .map_err(|e| RpcErrorCode::QueryFailure.custom(e))?; - Ok(resp) - } - pub(crate) async fn genesis_config(&self) -> Result { let resp = self .rpc_client @@ -400,20 +362,6 @@ impl Client { Ok(resp) } - pub(crate) async fn protocol_config( - &self, - block_reference: BlockReference, - ) -> Result { - let resp = self - .rpc_client - .call( - methods::EXPERIMENTAL_protocol_config::RpcProtocolConfigRequest { block_reference }, - ) - .await - .map_err(|e| RpcErrorCode::QueryFailure.custom(e))?; - Ok(resp) - } - pub(crate) async fn receipt(&self, receipt_reference: ReceiptReference) -> Result { let resp = self .rpc_client diff --git a/workspaces/src/rpc/query.rs b/workspaces/src/rpc/query.rs index 59b192b8..5343f091 100644 --- a/workspaces/src/rpc/query.rs +++ b/workspaces/src/rpc/query.rs @@ -43,6 +43,9 @@ use near_primitives::types::{BlockId, BlockReference, StoreKey}; use near_primitives::views::{BlockView, QueryRequest}; use near_token::NearToken; +#[cfg(feature = "experimental")] +use near_primitives::views::StateChangesRequestView; + use crate::error::RpcErrorCode; use crate::operations::Function; use crate::result::ViewResultDetails; @@ -185,6 +188,17 @@ pub struct ViewAccessKeyList { pub struct GasPrice; +#[cfg(feature = "experimental")] +pub struct StateChanges { + pub(crate) state_changes: StateChangesRequestView, +} + +#[cfg(feature = "experimental")] +pub struct StateChangesInBlock; + +#[cfg(feature = "experimental")] +pub struct ProtocolConfig; + impl ProcessQuery for ViewFunction { type Method = methods::query::RpcQueryRequest; type Output = ViewResultDetails; @@ -401,6 +415,55 @@ impl ProcessQuery for GasPrice { } } +#[cfg(feature = "experimental")] +impl ProcessQuery for StateChanges { + type Method = methods::EXPERIMENTAL_changes::RpcStateChangesInBlockByTypeRequest; + type Output = methods::EXPERIMENTAL_changes::RpcStateChangesInBlockResponse; + + fn into_request(self, block_ref: BlockReference) -> Result { + Ok(Self::Method { + block_reference: block_ref, + state_changes_request: self.state_changes, + }) + } + + fn from_response(resp: ::Response) -> Result { + Ok(resp) + } +} + +#[cfg(feature = "experimental")] +impl ProcessQuery for StateChangesInBlock { + type Method = methods::EXPERIMENTAL_changes_in_block::RpcStateChangesInBlockRequest; + type Output = methods::EXPERIMENTAL_changes_in_block::RpcStateChangesInBlockByTypeResponse; + + fn into_request(self, block_ref: BlockReference) -> Result { + Ok(Self::Method { + block_reference: block_ref, + }) + } + + fn from_response(resp: ::Response) -> Result { + Ok(resp) + } +} + +#[cfg(feature = "experimental")] +impl ProcessQuery for ProtocolConfig { + type Method = methods::EXPERIMENTAL_protocol_config::RpcProtocolConfigRequest; + type Output = methods::EXPERIMENTAL_protocol_config::RpcProtocolConfigResponse; + + fn into_request(self, block_ref: BlockReference) -> Result { + Ok(Self::Method { + block_reference: block_ref, + }) + } + + fn from_response(resp: ::Response) -> Result { + Ok(resp) + } +} + /// Query object used to query for chunk related details at a specific `ChunkReference` which /// consists of either a chunk [`CryptoHash`], or a `BlockShardId` (which consists of [`ShardId`] /// and either block [`CryptoHash`] or [`BlockHeight`]). diff --git a/workspaces/src/worker/impls.rs b/workspaces/src/worker/impls.rs index 84485ca3..198f3ef6 100644 --- a/workspaces/src/worker/impls.rs +++ b/workspaces/src/worker/impls.rs @@ -14,14 +14,12 @@ use crate::{Account, Network}; #[cfg(feature = "experimental")] use { - near_chain_configs::{GenesisConfig, ProtocolConfigView}, - near_jsonrpc_primitives::types::{ - changes::{RpcStateChangesInBlockByTypeResponse, RpcStateChangesInBlockResponse}, - receipts::ReceiptReference, - transactions::TransactionInfo, - }, + crate::rpc::query::{ProtocolConfig, StateChanges, StateChangesInBlock}, + crate::CryptoHash, + near_chain_configs::GenesisConfig, + near_jsonrpc_primitives::types::{receipts::ReceiptReference, transactions::TransactionInfo}, near_primitives::{ - types::{BlockReference, MaybeBlockId}, + types::MaybeBlockId, views::{ validator_stake_view::ValidatorStakeView, FinalExecutionOutcomeWithReceiptView, ReceiptView, StateChangesRequestView, @@ -200,22 +198,25 @@ where T: NetworkClient + Send + Sync + ?Sized, { /// Provides a list of changes in block associated with the given block reference. - pub async fn changes_in_block( - &self, - block_reference: BlockReference, - ) -> Result { - self.client().changes_in_block(block_reference).await + pub fn changes(&self, account_ids: &[AccountId]) -> Query<'_, StateChanges> { + Query::new( + self.client(), + StateChanges { + state_changes: StateChangesRequestView::AccountChanges { + account_ids: account_ids.to_vec(), + }, + }, + ) } /// Provides a list of changes in block associated with the given block reference and state changes request. - pub async fn changes( - &self, - block_reference: BlockReference, - state_changes_request: StateChangesRequestView, - ) -> Result { - self.client() - .changes(block_reference, state_changes_request) - .await + pub fn changes_in_block(&self) -> Query<'_, StateChangesInBlock> { + Query::new(self.client(), StateChangesInBlock) + } + + /// Provides a protocol config associated with the given block reference. + pub fn protocol_config(&self) -> Query<'_, ProtocolConfig> { + Query::new(self.client(), ProtocolConfig) } /// Provides a genesis config associated with the network being used. @@ -223,25 +224,27 @@ where self.client().genesis_config().await } - /// Provides a protocol config associated with the given block reference. - pub async fn protocol_config( - &self, - block_reference: BlockReference, - ) -> Result { - self.client().protocol_config(block_reference).await - } - /// Provides a receipt associated with the given receipt reference. - pub async fn receipt(&self, receipt_reference: ReceiptReference) -> Result { - self.client().receipt(receipt_reference).await + pub async fn receipt(&self, id: &CryptoHash) -> Result { + self.client() + .receipt(ReceiptReference { + receipt_id: near_primitives::hash::CryptoHash(id.0), + }) + .await } /// Returns the transaction status for a given transaction hash or signed transaction. pub async fn tx_status( &self, - transaction_info: TransactionInfo, + hash: CryptoHash, + account_id: AccountId, ) -> Result { - self.client().tx_status(transaction_info).await + self.client() + .tx_status(TransactionInfo::TransactionId { + hash: near_primitives::hash::CryptoHash(hash.0), + account_id, + }) + .await } /// Provides a list of validators ordered with respect to their stake.