From 070ac5601e504de1a50018d84577c4f11c7fbb54 Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Sun, 25 Jun 2023 18:18:44 +0300 Subject: [PATCH 01/11] FIX: many functions were not actually required to be async. Changed to sync. --- ton_client/src/abi/decode_boc.rs | 34 ++-- ton_client/src/abi/decode_data.rs | 4 +- ton_client/src/abi/decode_message.rs | 29 ++-- ton_client/src/abi/encode_account.rs | 20 +-- ton_client/src/abi/encode_boc.rs | 4 +- ton_client/src/abi/encode_message.rs | 22 ++- ton_client/src/abi/init_data.rs | 14 +- ton_client/src/abi/tests.rs | 10 +- ton_client/src/boc/blockchain_config.rs | 8 +- ton_client/src/boc/cache.rs | 8 +- ton_client/src/boc/common.rs | 10 +- ton_client/src/boc/encode.rs | 39 +++-- .../src/boc/encode_external_in_message.rs | 10 +- ton_client/src/boc/internal.rs | 12 +- ton_client/src/boc/parse.rs | 20 +-- ton_client/src/boc/state_init.rs | 76 ++++---- ton_client/src/boc/tests.rs | 36 +--- ton_client/src/boc/tvc.rs | 18 +- ton_client/src/client/tests.rs | 7 +- ton_client/src/debot/calltype.rs | 161 +++++++++++------ ton_client/src/debot/dengine.rs | 2 - ton_client/src/debot/dinterface.rs | 8 +- ton_client/src/debot/info.rs | 8 +- ton_client/src/debot/msg_interface.rs | 4 - ton_client/src/debot/routines.rs | 1 - ton_client/src/json_interface/modules.rs | 66 +++---- ton_client/src/net/transaction_tree.rs | 23 ++- ton_client/src/processing/fetching.rs | 4 +- ton_client/src/processing/internal.rs | 3 +- ton_client/src/processing/message_monitor.rs | 10 +- ton_client/src/processing/parsing.rs | 9 +- ton_client/src/processing/send_message.rs | 8 +- ton_client/src/processing/send_messages.rs | 3 +- ton_client/src/processing/tests.rs | 4 +- .../src/processing/wait_for_transaction.rs | 115 ++++++------ ton_client/src/tvm/run_get.rs | 2 +- ton_client/src/tvm/run_message.rs | 164 ++++++++++-------- ton_client/src/tvm/types.rs | 8 +- ton_client/src/utils/calc_storage_fee.rs | 55 +++--- .../src/message_monitor/monitor.rs | 6 +- 40 files changed, 541 insertions(+), 504 deletions(-) diff --git a/ton_client/src/abi/decode_boc.rs b/ton_client/src/abi/decode_boc.rs index 2587c6cec..6656c627b 100644 --- a/ton_client/src/abi/decode_boc.rs +++ b/ton_client/src/abi/decode_boc.rs @@ -18,7 +18,7 @@ pub struct ParamsOfDecodeBoc { pub boc: String, // Do not check if all BOC data is parsed by provided parameters set // Set it to `true` if don't need to decode the whole BOC data or if you need - // to handle conditional parsing (when TLB constructor or flags should be + // to handle conditional parsing (when TLB constructor or flags should be // checked to decide how to parse remaining BOC data) pub allow_partial: bool, } @@ -30,29 +30,29 @@ pub struct ResultOfDecodeBoc { } /// Decodes BOC into JSON as a set of provided parameters. -/// -/// Solidity functions use ABI types for [builder encoding](https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#tvmbuilderstore). -/// The simplest way to decode such a BOC is to use ABI decoding. -/// ABI has it own rules for fields layout in cells so manually encoded -/// BOC can not be described in terms of ABI rules. -/// -/// To solve this problem we introduce a new ABI type `Ref()` -/// which allows to store `ParamType` ABI parameter in cell reference and, thus, -/// decode manually encoded BOCs. This type is available only in `decode_boc` function +/// +/// Solidity functions use ABI types for [builder encoding](https://github.com/tonlabs/TON-Solidity-Compiler/blob/master/API.md#tvmbuilderstore). +/// The simplest way to decode such a BOC is to use ABI decoding. +/// ABI has it own rules for fields layout in cells so manually encoded +/// BOC can not be described in terms of ABI rules. +/// +/// To solve this problem we introduce a new ABI type `Ref()` +/// which allows to store `ParamType` ABI parameter in cell reference and, thus, +/// decode manually encoded BOCs. This type is available only in `decode_boc` function /// and will not be available in ABI messages encoding until it is included into some ABI revision. -/// -/// Such BOC descriptions covers most users needs. If someone wants to decode some BOC which -/// can not be described by these rules (i.e. BOC with TLB containing constructors of flags -/// defining some parsing conditions) then they can decode the fields up to fork condition, -/// check the parsed data manually, expand the parsing schema and then decode the whole BOC +/// +/// Such BOC descriptions covers most users needs. If someone wants to decode some BOC which +/// can not be described by these rules (i.e. BOC with TLB containing constructors of flags +/// defining some parsing conditions) then they can decode the fields up to fork condition, +/// check the parsed data manually, expand the parsing schema and then decode the whole BOC /// with the full schema. #[api_function] -pub async fn decode_boc( +pub fn decode_boc( context: Arc, params: ParamsOfDecodeBoc, ) -> ClientResult { - let (_, data) = deserialize_cell_from_boc(&context, ¶ms.boc, "").await?; + let (_, data) = deserialize_cell_from_boc(&context, ¶ms.boc, "")?; let mut abi_params = Vec::with_capacity(params.params.len()); for param in params.params { diff --git a/ton_client/src/abi/decode_data.rs b/ton_client/src/abi/decode_data.rs index 672b4f2ae..262f3b8dd 100644 --- a/ton_client/src/abi/decode_data.rs +++ b/ton_client/src/abi/decode_data.rs @@ -35,11 +35,11 @@ pub struct ResultOfDecodeAccountData { /// /// Note: this feature requires ABI 2.1 or higher. #[api_function] -pub async fn decode_account_data( +pub fn decode_account_data( context: Arc, params: ParamsOfDecodeAccountData, ) -> ClientResult { - let (_, data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data").await?; + let (_, data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data")?; let abi = params.abi.abi()?; let tokens = abi.decode_storage_fields(slice_from_cell(data)?, params.allow_partial) diff --git a/ton_client/src/abi/decode_message.rs b/ton_client/src/abi/decode_message.rs index b45c58190..dc4637ce3 100644 --- a/ton_client/src/abi/decode_message.rs +++ b/ton_client/src/abi/decode_message.rs @@ -100,19 +100,19 @@ pub struct ParamsOfDecodeMessage { /// Function name or function id if is known in advance pub function_name: Option, - // For external (inbound and outbound) messages data_layout parameter is ignored. - // For internal: by default SDK tries to decode as output and then if decode is not successfull - tries as input. - // If explicitly specified then tries only the specified layout. + // For external (inbound and outbound) messages data_layout parameter is ignored. + // For internal: by default SDK tries to decode as output and then if decode is not successfull - tries as input. + // If explicitly specified then tries only the specified layout. pub data_layout: Option, } /// Decodes message body using provided message BOC and ABI. #[api_function] -pub async fn decode_message( +pub fn decode_message( context: Arc, params: ParamsOfDecodeMessage, ) -> ClientResult { - let (abi, message) = prepare_decode(&context, ¶ms).await?; + let (abi, message) = prepare_decode(&context, ¶ms)?; if let Some(body) = message.body() { let data_layout = match message.header() { ton_block::CommonMsgInfo::ExtInMsgInfo(_) => Some(DataLayout::Input), @@ -151,29 +151,28 @@ pub struct ParamsOfDecodeMessageBody { pub function_name: Option, // By default SDK tries to decode as output and then if decode is not successfull - tries as input. - // If explicitly specified then tries only the specified layout. + // If explicitly specified then tries only the specified layout. pub data_layout: Option, } /// Decodes message body using provided body BOC and ABI. #[api_function] -pub async fn decode_message_body( +pub fn decode_message_body( context: Arc, params: ParamsOfDecodeMessageBody, ) -> ClientResult { let abi = params.abi.abi()?; - let (_, body) = deserialize_cell_from_boc(&context, ¶ms.body, "message body").await?; + let (_, body) = deserialize_cell_from_boc(&context, ¶ms.body, "message body")?; let body = slice_from_cell(body)?; decode_body(abi, body, params.is_internal, params.allow_partial, params.function_name, params.data_layout) } -async fn prepare_decode( +fn prepare_decode( context: &ClientContext, params: &ParamsOfDecodeMessage, ) -> ClientResult<(AbiContract, ton_block::Message)> { let abi = params.abi.abi()?; let message = deserialize_object_from_boc(context, ¶ms.message, "message") - .await .map_err(|x| Error::invalid_message_for_decode(x))?; Ok((abi, message.object)) } @@ -300,7 +299,7 @@ fn decode_with_function( function_name, tokens: decoded, }; - DecodedMessageBody::new(MessageBodyType::Event, decoded, None) + DecodedMessageBody::new(MessageBodyType::Event, decoded, None) } } } @@ -358,7 +357,7 @@ pub async fn get_signature_data( params: ParamsOfGetSignatureData, ) -> ClientResult { let abi = params.abi.abi()?; - let message: ton_block::Message = deserialize_object_from_boc(&context, ¶ms.message, "message").await?.object; + let message: ton_block::Message = deserialize_object_from_boc(&context, ¶ms.message, "message")?.object; if let Some(body) = message.body() { let address = message.dst() .ok_or_else(|| Error::invalid_message_for_decode( @@ -367,8 +366,8 @@ pub async fn get_signature_data( let (signature, hash) = abi.get_signature_data(body, Some(address)) .map_err(|err| Error::invalid_message_for_decode(err))?; let unsigned = extend_data_to_sign(&context, params.signature_id, Some(hash)).await?; - Ok(ResultOfGetSignatureData { - signature: hex::encode(&signature), + Ok(ResultOfGetSignatureData { + signature: hex::encode(&signature), unsigned: base64::encode(&unsigned.unwrap()), }) } else { @@ -376,4 +375,4 @@ pub async fn get_signature_data( "The message body is empty", )) } -} \ No newline at end of file +} diff --git a/ton_client/src/abi/encode_account.rs b/ton_client/src/abi/encode_account.rs index 39384b6a0..1a9c14c27 100644 --- a/ton_client/src/abi/encode_account.rs +++ b/ton_client/src/abi/encode_account.rs @@ -84,25 +84,25 @@ async fn state_init_from_message( let (message, _) = message.encode(context).await?; let message = deserialize_object_from_boc::( context, &message, "message" - ).await?.object; + )?.object; message .state_init() .map(|x| x.clone()) .ok_or(Error::invalid_message_for_decode("missing `state_init`")) } -async fn state_init_from_bocs( +fn state_init_from_bocs( context: &ClientContext, code: &String, data: &String, library: &Option, ) -> ClientResult { Ok(StateInit { - code: Some(deserialize_cell_from_boc(context, code, "account code").await?.1), - data: Some(deserialize_cell_from_boc(context, data, "account data").await?.1), + code: Some(deserialize_cell_from_boc(context, code, "account code")?.1), + data: Some(deserialize_cell_from_boc(context, data, "account data")?.1), library: if let Some(library) = library { StateInitLib::with_hashmap( - Some(deserialize_cell_from_boc(context, library, "library").await?.1) + Some(deserialize_cell_from_boc(context, library, "library")?.1) ) } else { StateInitLib::default() @@ -112,13 +112,13 @@ async fn state_init_from_bocs( }) } -async fn state_init_from_tvc( +fn state_init_from_tvc( context: &ClientContext, tvc: &String, public_key: &Option, init_params: &Option, ) -> ClientResult { - let (_, cell) = deserialize_cell_from_boc(context, tvc, "TVC image").await?; + let (_, cell) = deserialize_cell_from_boc(context, tvc, "TVC image")?; let public_key = public_key .as_ref() .map(|x| decode_public_key(x)) @@ -160,12 +160,12 @@ pub async fn encode_account( code, data, library, - } => state_init_from_bocs(&context, code, data, library).await, + } => state_init_from_bocs(&context, code, data, library), StateInitSource::Tvc { tvc, public_key, init_params, - } => state_init_from_tvc(&context, tvc, public_key, init_params).await, + } => state_init_from_tvc(&context, tvc, public_key, init_params), }?; let id = state_init.hash().map_err(|err| Error::invalid_tvc_image(err))?; let address = MsgAddressInt::with_standart(None, 0, id.clone().into()).unwrap(); @@ -175,7 +175,7 @@ pub async fn encode_account( .map_err(|err| Error::invalid_tvc_image(err))?; account.set_last_tr_time(params.last_trans_lt.unwrap_or(0)); Ok(ResultOfEncodeAccount { - account: serialize_object_to_boc(&context, &account, "account", params.boc_cache).await?, + account: serialize_object_to_boc(&context, &account, "account", params.boc_cache)?, id: id.as_hex_string(), }) } diff --git a/ton_client/src/abi/encode_boc.rs b/ton_client/src/abi/encode_boc.rs index 02fd6624a..3cd1ea0dd 100644 --- a/ton_client/src/abi/encode_boc.rs +++ b/ton_client/src/abi/encode_boc.rs @@ -30,7 +30,7 @@ pub struct ResultOfAbiEncodeBoc { /// Encodes given parameters in JSON into a BOC using param types from ABI. #[api_function] -pub async fn encode_boc( +pub fn encode_boc( context: Arc, params: ParamsOfAbiEncodeBoc, ) -> ClientResult { @@ -49,6 +49,6 @@ pub async fn encode_boc( .map_err(|err| Error::invalid_abi(err))?; Ok(ResultOfAbiEncodeBoc { - boc: serialize_cell_to_boc(&context, cell, "ABI params", params.boc_cache).await?, + boc: serialize_cell_to_boc(&context, cell, "ABI params", params.boc_cache)?, }) } diff --git a/ton_client/src/abi/encode_message.rs b/ton_client/src/abi/encode_message.rs index 14a0dbe79..091301df5 100644 --- a/ton_client/src/abi/encode_message.rs +++ b/ton_client/src/abi/encode_message.rs @@ -60,19 +60,17 @@ impl DeploySet { }) } - pub async fn get_state_init(&self, context: &ClientContext) -> ClientResult { + pub fn get_state_init(&self, context: &ClientContext) -> ClientResult { let error = |err| Err(Error::encode_deploy_message_failed(err)); match (&self.tvc, &self.code, &self.state_init) { (Some(tvc_or_state_init), None, None) => { - resolve_state_init_cell(context, tvc_or_state_init).await + resolve_state_init_cell(context, tvc_or_state_init) } (None, Some(code), None) => { - state_init_with_code(deserialize_cell_from_boc(context, code, "code").await?.1) + state_init_with_code(deserialize_cell_from_boc(context, code, "code")?.1) } (None, None, Some(state_init)) => { - Ok(deserialize_cell_from_boc(context, state_init, "state init") - .await? - .1) + Ok(deserialize_cell_from_boc(context, state_init, "state init")?.1) } (None, None, None) => error( "at least one of the `tvc`, `code` or `state_init` value should be specified.", @@ -508,7 +506,7 @@ pub async fn encode_message( let mut image = create_tvc_image( &abi, deploy_set.initial_data.as_ref(), - deploy_set.get_state_init(&context).await?, + deploy_set.get_state_init(&context)?, )?; required_public_key(update_pubkey(&deploy_set, &mut image, &public)?)?; @@ -652,7 +650,7 @@ pub async fn encode_internal_message( let mut image = create_tvc_image( &abi, deploy_set.initial_data.as_ref(), - deploy_set.get_state_init(&context).await?, + deploy_set.get_state_init(&context)?, )?; let public = update_pubkey(&deploy_set, &mut image, &None)?; @@ -892,11 +890,11 @@ pub struct ResultOfAttachSignature { /// Combines `hex`-encoded `signature` with `base64`-encoded `unsigned_message`. /// Returns signed message encoded in `base64`. #[api_function] -pub async fn attach_signature( +pub fn attach_signature( context: Arc, params: ParamsOfAttachSignature, ) -> ClientResult { - let (boc, _) = deserialize_cell_from_boc(&context, ¶ms.message, "message").await?; + let (boc, _) = deserialize_cell_from_boc(&context, ¶ms.message, "message")?; let signed = add_sign_to_message( ¶ms.abi.json_string()?, &hex_decode(¶ms.signature)?, @@ -933,11 +931,11 @@ pub struct ResultOfAttachSignatureToMessageBody { /// #[api_function] -pub async fn attach_signature_to_message_body( +pub fn attach_signature_to_message_body( context: Arc, params: ParamsOfAttachSignatureToMessageBody, ) -> ClientResult { - let (boc, _) = deserialize_cell_from_boc(&context, ¶ms.message, "message body").await?; + let (boc, _) = deserialize_cell_from_boc(&context, ¶ms.message, "message body")?; let signed = add_sign_to_message_body( ¶ms.abi.json_string()?, &hex_decode(¶ms.signature)?, diff --git a/ton_client/src/abi/init_data.rs b/ton_client/src/abi/init_data.rs index a663bf83e..57e97ac9f 100644 --- a/ton_client/src/abi/init_data.rs +++ b/ton_client/src/abi/init_data.rs @@ -36,16 +36,16 @@ pub struct ResultOfUpdateInitialData { /// This operation is applicable only for initial account data (before deploy). /// If the contract is already deployed, its data doesn't contain this data section any more. #[api_function] -pub async fn update_initial_data( +pub fn update_initial_data( context: Arc, params: ParamsOfUpdateInitialData, ) -> ClientResult { - let (_, mut data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data").await?; + let (_, mut data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data")?; data = update_initial_data_internal(¶ms.initial_data, ¶ms.abi, ¶ms.initial_pubkey, data)?; Ok(ResultOfUpdateInitialData { - data: serialize_cell_to_boc(&context, data, "contract data", params.boc_cache).await? + data: serialize_cell_to_boc(&context, data, "contract data", params.boc_cache)? }) } @@ -110,7 +110,7 @@ pub struct ResultOfEncodeInitialData { /// /// This function is analogue of `tvm.buildDataInit` function in Solidity. #[api_function] -pub async fn encode_initial_data( +pub fn encode_initial_data( context: Arc, params: ParamsOfEncodeInitialData, ) -> ClientResult { @@ -122,7 +122,7 @@ pub async fn encode_initial_data( )?; Ok(ResultOfEncodeInitialData { - data: serialize_cell_to_boc(&context, data, "contract data", params.boc_cache).await? + data: serialize_cell_to_boc(&context, data, "contract data", params.boc_cache)? }) } @@ -152,11 +152,11 @@ pub struct ResultOfDecodeInitialData { /// This operation is applicable only for initial account data (before deploy). /// If the contract is already deployed, its data doesn't contain this data section any more. #[api_function] -pub async fn decode_initial_data( +pub fn decode_initial_data( context: Arc, params: ParamsOfDecodeInitialData, ) -> ClientResult { - let (_, data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data").await?; + let (_, data) = deserialize_cell_from_boc(&context, ¶ms.data, "contract data")?; let data = slice_from_cell(data)?; let initial_pubkey = ton_abi::Contract::get_pubkey(&data) diff --git a/ton_client/src/abi/tests.rs b/ton_client/src/abi/tests.rs index 3be964755..0e47a53ed 100644 --- a/ton_client/src/abi/tests.rs +++ b/ton_client/src/abi/tests.rs @@ -474,7 +474,7 @@ async fn test_resolve_pubkey() -> Result<()> { tvc: Some(tvc.clone()), ..Default::default() }; - let mut image = create_tvc_image("", None, resolve_state_init_cell(&context, &tvc).await?)?; + let mut image = create_tvc_image("", None, resolve_state_init_cell(&context, &tvc)?)?; assert!(resolve_pubkey(&deploy_set, &image, &None)?.is_none()); let external_pub_key = @@ -591,7 +591,7 @@ async fn test_encode_message_pubkey_internal( let mut image = create_tvc_image( &abi.json_string()?, None, - resolve_state_init_cell(&context, tvc.as_ref().unwrap()).await?, + resolve_state_init_cell(&context, tvc.as_ref().unwrap())?, )?; if let Some(tvc_pubkey) = tvc_pubkey { image.set_public_key(tvc_pubkey)?; @@ -648,7 +648,7 @@ async fn test_encode_internal_message() -> Result<()> { let image = create_tvc_image( &abi.json_string()?, None, - resolve_state_init_cell(&context, tvc.as_ref().unwrap()).await?, + resolve_state_init_cell(&context, tvc.as_ref().unwrap())?, )?; let address = String::from("0:1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef"); @@ -1345,7 +1345,7 @@ async fn test_deploy_code_variants_with_fn< secret: "cc8929d635719612a9478b9cd17675a39cfad52d8959e8a177389b8c0b9122a7".into(), }; let state_init_cell = - resolve_state_init_cell(&client.context(), &unknown_tvc.clone().unwrap()).await?; + resolve_state_init_cell(&client.context(), &unknown_tvc.clone().unwrap())?; let state_init = deserialize_object_from_cell::(state_init_cell.clone(), "state init")?; @@ -1448,7 +1448,6 @@ async fn encode_internal_deploy( boc: encoded.message, }, ) - .await .unwrap() .parsed } @@ -1486,7 +1485,6 @@ async fn encode_deploy( boc: encoded.message, }, ) - .await .unwrap() .parsed } diff --git a/ton_client/src/boc/blockchain_config.rs b/ton_client/src/boc/blockchain_config.rs index 7bb09b080..5f756d4f1 100644 --- a/ton_client/src/boc/blockchain_config.rs +++ b/ton_client/src/boc/blockchain_config.rs @@ -31,18 +31,18 @@ pub struct ResultOfGetBlockchainConfig { /// Extract blockchain configuration from key block and also from zerostate. #[api_function] -pub async fn get_blockchain_config( +pub fn get_blockchain_config( context: std::sync::Arc, params: ParamsOfGetBlockchainConfig, ) -> ClientResult { - let config = if let Ok(block) = - deserialize_object_from_boc::(&context, ¶ms.block_boc, "block").await + let config = if let Ok(block) = + deserialize_object_from_boc::(&context, ¶ms.block_boc, "block") { extract_config_from_block(&block.object)? } else { let zerostate = deserialize_object_from_boc::( &context, ¶ms.block_boc, "zerostate" - ).await?; + )?; extract_config_from_zerostate(&zerostate.object)? }; diff --git a/ton_client/src/boc/cache.rs b/ton_client/src/boc/cache.rs index 36d12c099..07b1572dd 100644 --- a/ton_client/src/boc/cache.rs +++ b/ton_client/src/boc/cache.rs @@ -322,11 +322,11 @@ pub struct ResultOfBocCacheSet { /// Save BOC into cache or increase pin counter for existing pinned BOC #[api_function] -pub async fn cache_set( +pub fn cache_set( context: Arc, params: ParamsOfBocCacheSet, ) -> ClientResult { - let (bytes, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "BOC").await?; + let (bytes, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "BOC")?; let size = match bytes { DeserializedBoc::Bytes(bytes) => Some(bytes.len()), _ => None, @@ -353,7 +353,7 @@ pub struct ResultOfBocCacheGet { /// Get BOC from cache #[api_function] -pub async fn cache_get( +pub fn cache_get( context: Arc, params: ParamsOfBocCacheGet, ) -> ClientResult { @@ -380,7 +380,7 @@ pub struct ParamsOfBocCacheUnpin { /// Decrease pin reference counter for BOCs with specified pin defined in the `cache_set`. /// BOCs which have only 1 pin and its reference counter become 0 will be removed from cache #[api_function] -pub async fn cache_unpin( +pub fn cache_unpin( context: Arc, params: ParamsOfBocCacheUnpin, ) -> ClientResult<()> { diff --git a/ton_client/src/boc/common.rs b/ton_client/src/boc/common.rs index ea3303362..d04174408 100644 --- a/ton_client/src/boc/common.rs +++ b/ton_client/src/boc/common.rs @@ -29,11 +29,11 @@ pub struct ResultOfGetBocHash { /// Calculates BOC root hash #[api_function] -pub async fn get_boc_hash( +pub fn get_boc_hash( context: std::sync::Arc, params: ParamsOfGetBocHash, ) -> ClientResult { - let (_, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "").await?; + let (_, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "")?; let hash = cell.repr_hash().as_hex_string(); Ok(ResultOfGetBocHash { hash }) } @@ -52,12 +52,12 @@ pub struct ResultOfGetBocDepth { /// Calculates BOC depth #[api_function] -pub async fn get_boc_depth( +pub fn get_boc_depth( context: std::sync::Arc, params: ParamsOfGetBocDepth, ) -> ClientResult { - let (_, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "").await?; - Ok(ResultOfGetBocDepth { + let (_, cell) = deserialize_cell_from_boc(&context, ¶ms.boc, "")?; + Ok(ResultOfGetBocDepth { depth: cell.repr_depth() as u32 }) } diff --git a/ton_client/src/boc/encode.rs b/ton_client/src/boc/encode.rs index 3ae6c0e75..c2701b47c 100644 --- a/ton_client/src/boc/encode.rs +++ b/ton_client/src/boc/encode.rs @@ -8,10 +8,10 @@ use ton_types::{BuilderData, Cell, IBitstring}; use super::{internal::serialize_cell_to_boc, Error}; use crate::boc::internal::deserialize_cell_from_boc; use crate::boc::BocCacheType; +use crate::encoding::account_decode; use num_bigint::{BigInt, BigUint, Sign}; use num_traits::Num; use std::ops::ShlAssign; -use crate::encoding::account_decode; /// Cell builder operation. #[derive(Serialize, Deserialize, Clone, ApiType)] @@ -61,7 +61,7 @@ pub enum BuilderOp { Address { /// Address in a common `workchain:account` or base64 format. address: String, - } + }, } impl Default for BuilderOp { @@ -90,17 +90,17 @@ pub struct ResultOfEncodeBoc { /// Encodes bag of cells (BOC) with builder operations. /// This method provides the same functionality as Solidity TvmBuilder. -/// Resulting BOC of this method can be passed into +/// Resulting BOC of this method can be passed into /// Solidity and C++ contracts as TvmCell type. #[api_function] -pub async fn encode_boc( +pub fn encode_boc( context: std::sync::Arc, params: ParamsOfEncodeBoc, ) -> ClientResult { let mut stack = Vec::::new(); let mut builder = Builder::new(¶ms.builder); loop { - match builder.build(&context).await? { + match builder.build(&context)? { BuildResult::Nested { nested, prev } => { stack.push(prev); builder = nested; @@ -108,13 +108,18 @@ pub async fn encode_boc( BuildResult::Complete(cell) => { if let Some(prev) = stack.pop() { builder = prev; - builder.result.checked_append_reference(cell).map_err( - |err| Error::serialization_error(err, "encoded cell"), - )?; + builder + .result + .checked_append_reference(cell) + .map_err(|err| Error::serialization_error(err, "encoded cell"))?; } else { return Ok(ResultOfEncodeBoc { - boc: serialize_cell_to_boc(&context, cell, "encoded cell", params.boc_cache) - .await?, + boc: serialize_cell_to_boc( + &context, + cell, + "encoded cell", + params.boc_cache, + )?, }); } } @@ -145,7 +150,7 @@ impl<'a> Builder<'a> { /// Append data using operation iterator until the end or the nested cell operation. /// Returns resulting cell or nested Builder. - async fn build( + fn build( mut self, context: &std::sync::Arc, ) -> ClientResult> { @@ -158,13 +163,11 @@ impl<'a> Builder<'a> { append_bitstring(&mut self.result, &value)?; } BuilderOp::CellBoc { boc } => { - self.result.checked_append_reference( - deserialize_cell_from_boc(context, boc, "CellBoc") - .await? - .1, - ).map_err( - |err| Error::serialization_error(err, "encode_boc"), - )?; + self.result + .checked_append_reference( + deserialize_cell_from_boc(context, boc, "CellBoc")?.1, + ) + .map_err(|err| Error::serialization_error(err, "encode_boc"))?; } BuilderOp::Cell { ref builder } => { return Ok(BuildResult::Nested { diff --git a/ton_client/src/boc/encode_external_in_message.rs b/ton_client/src/boc/encode_external_in_message.rs index fe9924806..5fd4f591b 100644 --- a/ton_client/src/boc/encode_external_in_message.rs +++ b/ton_client/src/boc/encode_external_in_message.rs @@ -40,7 +40,7 @@ pub struct ResultOfEncodeExternalInMessage { /// Allows to encode any external inbound message. /// #[api_function] -pub async fn encode_external_in_message( +pub fn encode_external_in_message( context: std::sync::Arc, params: ParamsOfEncodeExternalInMessage, ) -> ClientResult { @@ -63,20 +63,18 @@ pub async fn encode_external_in_message( let mut msg = ton_block::Message::with_ext_in_header(header); if let Some(init) = params.init { msg.set_state_init( - deserialize_object_from_boc::(&context, &init, "state init") - .await? - .object, + deserialize_object_from_boc::(&context, &init, "state init")?.object, ); } if let Some(body) = params.body { - let (_, cell) = deserialize_cell_from_boc(&context, &body, "message body").await?; + let (_, cell) = deserialize_cell_from_boc(&context, &body, "message body")?; msg.set_body(slice_from_cell(cell)?); } let hash = msg .hash() .map_err(|err| crate::client::errors::Error::internal_error(err))?; - let boc = serialize_object_to_boc(&context, &msg, "message", params.boc_cache).await?; + let boc = serialize_object_to_boc(&context, &msg, "message", params.boc_cache)?; Ok(ResultOfEncodeExternalInMessage { message: boc, message_id: hex::encode(hash), diff --git a/ton_client/src/boc/internal.rs b/ton_client/src/boc/internal.rs index b7dad2d6c..c04592f3e 100644 --- a/ton_client/src/boc/internal.rs +++ b/ton_client/src/boc/internal.rs @@ -125,16 +125,16 @@ pub fn serialize_object_to_base64( Ok(serialize_cell_to_base64(&cell, name)?) } -pub async fn deserialize_cell_from_boc( +pub fn deserialize_cell_from_boc( context: &ClientContext, boc: &str, name: &str ) -> ClientResult<(DeserializedBoc, ton_types::Cell)> { context.bocs.deserialize_cell(boc, name) } -pub async fn deserialize_object_from_boc( +pub fn deserialize_object_from_boc( context: &ClientContext, boc: &str, name: &str, ) -> ClientResult> { - let (boc, cell) = deserialize_cell_from_boc(context, boc, name).await?; + let (boc, cell) = deserialize_cell_from_boc(context, boc, name)?; let object = deserialize_object_from_cell(cell.clone(), name)?; @@ -152,7 +152,7 @@ pub fn deserialize_object_from_boc_bin( Ok((object, root_hash)) } -pub async fn serialize_cell_to_boc( +pub fn serialize_cell_to_boc( context: &ClientContext, cell: ton_types::Cell, name: &str, boc_cache: Option, ) -> ClientResult { if let Some(cache_type) = boc_cache { @@ -165,9 +165,9 @@ pub async fn serialize_cell_to_boc( } } -pub async fn serialize_object_to_boc( +pub fn serialize_object_to_boc( context: &ClientContext, object: &S,name: &str, boc_cache: Option, ) -> ClientResult { let cell = serialize_object_to_cell(object, name)?; - serialize_cell_to_boc(context, cell, name, boc_cache).await + serialize_cell_to_boc(context, cell, name, boc_cache) } diff --git a/ton_client/src/boc/parse.rs b/ton_client/src/boc/parse.rs index 5bf965b06..76eaef4ab 100644 --- a/ton_client/src/boc/parse.rs +++ b/ton_client/src/boc/parse.rs @@ -43,11 +43,11 @@ pub struct ResultOfParse { /// /// JSON structure is compatible with GraphQL API message object #[api_function] -pub async fn parse_message( +pub fn parse_message( context: std::sync::Arc, params: ParamsOfParse, ) -> ClientResult { - let object = deserialize_object_from_boc::(&context, ¶ms.boc, "message").await?; + let object = deserialize_object_from_boc::(&context, ¶ms.boc, "message")?; let set = ton_block_json::MessageSerializationSet { block_id: None, @@ -77,12 +77,12 @@ pub async fn parse_message( /// /// JSON structure is compatible with GraphQL API transaction object #[api_function] -pub async fn parse_transaction( +pub fn parse_transaction( context: std::sync::Arc, params: ParamsOfParse, ) -> ClientResult { let object = - deserialize_object_from_boc::(&context, ¶ms.boc, "transaction").await?; + deserialize_object_from_boc::(&context, ¶ms.boc, "transaction")?; let set = ton_block_json::TransactionSerializationSetEx { block_id: None, @@ -110,11 +110,11 @@ pub async fn parse_transaction( /// /// JSON structure is compatible with GraphQL API account object #[api_function] -pub async fn parse_account( +pub fn parse_account( context: std::sync::Arc, params: ParamsOfParse, ) -> ClientResult { - let object = deserialize_object_from_boc::(&context, ¶ms.boc, "account").await?; + let object = deserialize_object_from_boc::(&context, ¶ms.boc, "account")?; let set = ton_block_json::AccountSerializationSet { boc: object.boc.bytes("account")?, @@ -139,11 +139,11 @@ pub async fn parse_account( /// /// JSON structure is compatible with GraphQL API block object #[api_function] -pub async fn parse_block( +pub fn parse_block( context: std::sync::Arc, params: ParamsOfParse, ) -> ClientResult { - let object = deserialize_object_from_boc::(&context, ¶ms.boc, "block").await?; + let object = deserialize_object_from_boc::(&context, ¶ms.boc, "block")?; let set = ton_block_json::BlockSerializationSet { boc: object.boc.bytes("block")?, @@ -169,12 +169,12 @@ pub async fn parse_block( /// /// JSON structure is compatible with GraphQL API shardstate object #[api_function] -pub async fn parse_shardstate( +pub fn parse_shardstate( context: std::sync::Arc, params: ParamsOfParseShardstate, ) -> ClientResult { let object = - deserialize_object_from_boc::(&context, ¶ms.boc, "shardstate").await?; + deserialize_object_from_boc::(&context, ¶ms.boc, "shardstate")?; let set = ton_block_json::ShardStateSerializationSet { boc: object.boc.bytes("shardstate")?, diff --git a/ton_client/src/boc/state_init.rs b/ton_client/src/boc/state_init.rs index 3549d6765..c9e8e1591 100644 --- a/ton_client/src/boc/state_init.rs +++ b/ton_client/src/boc/state_init.rs @@ -14,6 +14,7 @@ use ton_block::{Number5, StateInit, StateInitLib, TickTock}; use ton_types::{BuilderData, Cell}; +use super::BocCacheType; use crate::boc::internal::{ deserialize_cell_from_boc, deserialize_object_from_boc, deserialize_object_from_cell, serialize_cell_to_boc, serialize_object_to_boc, @@ -24,8 +25,6 @@ use crate::client::ClientContext; use crate::encoding::slice_from_cell; use crate::error::ClientResult; -use super::BocCacheType; - const OLD_CPP_SELECTOR_DATA: &[u8] = &[ 0xff, 0x00, 0x20, 0xc1, 0x01, 0xf4, 0xa4, 0x20, 0x58, 0x92, 0xf4, 0xa0, 0xe0, 0x5f, 0x02, 0x8a, 0x20, 0xed, 0x53, 0xd9, @@ -54,11 +53,11 @@ pub struct ResultOfGetCodeFromTvc { /// Extracts code from TVC contract image #[api_function] -pub async fn get_code_from_tvc( +pub fn get_code_from_tvc( context: std::sync::Arc, params: ParamsOfGetCodeFromTvc, ) -> ClientResult { - let state_init_cell = resolve_state_init_cell(&context, ¶ms.tvc).await?; + let state_init_cell = resolve_state_init_cell(&context, ¶ms.tvc)?; let object = deserialize_object_from_cell::(state_init_cell, "TVC")?; let code = object @@ -129,16 +128,21 @@ pub struct ResultOfGetCodeSalt { /// Returns the contract code's salt if it is present. #[api_function] -pub async fn get_code_salt( +pub fn get_code_salt( context: std::sync::Arc, params: ParamsOfGetCodeSalt, ) -> ClientResult { - let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code").await?; + let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code")?; let (salt, _) = get_salt_and_ver(code)?; let salt = if let Some(salt) = salt { - Some(serialize_cell_to_boc(&context, salt, "code salt", params.boc_cache).await?) + Some(serialize_cell_to_boc( + &context, + salt, + "code salt", + params.boc_cache, + )?) } else { None }; @@ -220,12 +224,12 @@ pub struct ResultOfSetCodeSalt { /// Sets new salt to contract code. Returns the new contract code with salt. #[api_function] -pub async fn set_code_salt( +pub fn set_code_salt( context: std::sync::Arc, params: ParamsOfSetCodeSalt, ) -> ClientResult { - let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code").await?; - let (_, salt) = deserialize_cell_from_boc(&context, ¶ms.salt, "salt").await?; + let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code")?; + let (_, salt) = deserialize_cell_from_boc(&context, ¶ms.salt, "salt")?; let code = match code.data() { OLD_CPP_SELECTOR_DATA => set_old_selector_salt(code, salt), @@ -238,7 +242,7 @@ pub async fn set_code_salt( }?; Ok(ResultOfSetCodeSalt { - code: serialize_cell_to_boc(&context, code, "contract code", params.boc_cache).await?, + code: serialize_cell_to_boc(&context, code, "contract code", params.boc_cache)?, }) } @@ -269,11 +273,11 @@ pub fn get_compiler_version_from_cell(code: Cell) -> ClientResult /// Returns the compiler version used to compile the code. #[api_function] -pub async fn get_compiler_version( +pub fn get_compiler_version( context: std::sync::Arc, params: ParamsOfGetCompilerVersion, ) -> ClientResult { - let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code").await?; + let (_, code) = deserialize_cell_from_boc(&context, ¶ms.code, "contract code")?; let version = get_compiler_version_from_cell(code)?; Ok(ResultOfGetCompilerVersion { version }) @@ -307,25 +311,21 @@ pub struct ResultOfEncodeStateInit { /// Encodes initial contract state from code, data, libraries ans special options (see input params) #[api_function] -pub async fn encode_state_init( +pub fn encode_state_init( context: std::sync::Arc, params: ParamsOfEncodeStateInit, ) -> ClientResult { let get_cell = |name, boc| { let context = context.clone(); - async move { - if let Some(boc) = boc { - deserialize_cell_from_boc(&context, boc, name) - .await - .map(|val| Some(val.1)) - } else { - Ok(None) - } + if let Some(boc) = boc { + deserialize_cell_from_boc(&context, boc, name).map(|val| Some(val.1)) + } else { + Ok(None) } }; - let code = get_cell("code", params.code.as_deref()).await?; - let data = get_cell("data", params.data.as_deref()).await?; - let library = StateInitLib::with_hashmap(get_cell("library", params.library.as_deref()).await?); + let code = get_cell("code", params.code.as_deref())?; + let data = get_cell("data", params.data.as_deref())?; + let library = StateInitLib::with_hashmap(get_cell("library", params.library.as_deref())?); let special = if params.tick.is_some() || params.tock.is_some() { Some(TickTock { @@ -349,7 +349,7 @@ pub async fn encode_state_init( }; Ok(ResultOfEncodeStateInit { - state_init: serialize_object_to_boc(&context, &state, "TVC", params.boc_cache).await?, + state_init: serialize_object_to_boc(&context, &state, "TVC", params.boc_cache)?, }) } @@ -390,23 +390,18 @@ pub struct ResultOfDecodeStateInit { /// Decodes contract's initial state into code, data, libraries and special options. #[api_function] -pub async fn decode_state_init( +pub fn decode_state_init( context: std::sync::Arc, params: ParamsOfDecodeStateInit, ) -> ClientResult { - let state_init = - deserialize_object_from_boc::(&context, ¶ms.state_init, "TVC").await?; + let state_init = deserialize_object_from_boc::(&context, ¶ms.state_init, "TVC")?; let serialize = |name, cell, boc_cache| { let context = context.clone(); - async move { - if let Some(cell) = cell { - serialize_cell_to_boc(&context, cell, name, boc_cache) - .await - .map(Some) - } else { - Ok(None) - } + if let Some(cell) = cell { + serialize_cell_to_boc(&context, cell, name, boc_cache).map(Some) + } else { + Ok(None) } }; let code_depth = state_init @@ -426,7 +421,7 @@ pub async fn decode_state_init( .map(|cell| get_compiler_version_from_cell(cell).ok()) .flatten() .flatten(); - let code = serialize("code", state_init.object.code, params.boc_cache.clone()).await?; + let code = serialize("code", state_init.object.code, params.boc_cache.clone())?; let data_depth = state_init .object @@ -438,14 +433,13 @@ pub async fn decode_state_init( .data .as_ref() .map(|cell| cell.repr_hash().as_hex_string()); - let data = serialize("data", state_init.object.data, params.boc_cache.clone()).await?; + let data = serialize("data", state_init.object.data, params.boc_cache.clone())?; let library = serialize( "library", state_init.object.library.root().cloned(), params.boc_cache.clone(), - ) - .await?; + )?; Ok(ResultOfDecodeStateInit { code, diff --git a/ton_client/src/boc/tests.rs b/ton_client/src/boc/tests.rs index 63c95d492..7925a862a 100644 --- a/ton_client/src/boc/tests.rs +++ b/ton_client/src/boc/tests.rs @@ -69,7 +69,7 @@ async fn test_encode_boc() { } let client = TestClient::new(); - let encode_boc = client.wrap_async( + let encode_boc = client.wrap( encode_boc, BocModule::api(), super::encode::encode_boc_api(), @@ -154,7 +154,6 @@ async fn test_encode_boc() { ], boc_cache: None, }) - .await .unwrap(); assert_eq!(boc, response.boc); @@ -179,7 +178,6 @@ async fn test_encode_boc() { ], boc_cache: None, }) - .await .unwrap(); assert_eq!(boc, response.boc); } @@ -187,9 +185,9 @@ async fn test_encode_boc() { #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn test_pinned_cache() { let client = TestClient::new(); - let cache_set = client.wrap_async(cache_set, BocModule::api(), super::cache::cache_set_api()); - let cache_get = client.wrap_async(cache_get, BocModule::api(), super::cache::cache_get_api()); - let cache_unpin = client.wrap_async( + let cache_set = client.wrap(cache_set, BocModule::api(), super::cache::cache_set_api()); + let cache_get = client.wrap(cache_get, BocModule::api(), super::cache::cache_get_api()); + let cache_unpin = client.wrap( cache_unpin, BocModule::api(), super::cache::cache_unpin_api(), @@ -206,7 +204,6 @@ async fn test_pinned_cache() { boc: boc1.clone(), cache_type: BocCacheType::Pinned { pin: pin1.clone() }, }) - .await .unwrap() .boc_ref; @@ -217,7 +214,6 @@ async fn test_pinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc1.clone())); @@ -226,7 +222,6 @@ async fn test_pinned_cache() { boc: boc2.clone(), cache_type: BocCacheType::Pinned { pin: pin1.clone() }, }) - .await .unwrap() .boc_ref; assert_ne!(ref2, ref1); @@ -236,7 +231,6 @@ async fn test_pinned_cache() { boc: boc1.clone(), cache_type: BocCacheType::Pinned { pin: pin2.clone() }, }) - .await .unwrap() .boc_ref; assert_eq!(ref3, ref1); @@ -248,14 +242,12 @@ async fn test_pinned_cache() { boc_ref: None, pin: pin1.clone(), }) - .await .unwrap(); let boc = cache_get .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc1.clone())); @@ -263,7 +255,6 @@ async fn test_pinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref2.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, None); @@ -272,7 +263,6 @@ async fn test_pinned_cache() { boc: boc2, cache_type: BocCacheType::Pinned { pin: pin2.clone() }, }) - .await .unwrap() .boc_ref; @@ -282,14 +272,12 @@ async fn test_pinned_cache() { boc_ref: Some(ref4.clone()), pin: pin2.clone(), }) - .await .unwrap(); let boc = cache_get .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc1.clone())); @@ -297,7 +285,6 @@ async fn test_pinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref4.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, None); @@ -308,7 +295,6 @@ async fn test_pinned_cache() { boc: ref1.clone(), cache_type: BocCacheType::Pinned { pin: pin2.clone() }, }) - .await .unwrap(); cache_unpin @@ -316,13 +302,11 @@ async fn test_pinned_cache() { boc_ref: None, pin: pin2.clone(), }) - .await .unwrap(); let boc = cache_get .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc1)); @@ -331,13 +315,11 @@ async fn test_pinned_cache() { boc_ref: None, pin: pin2.clone(), }) - .await .unwrap(); let boc = cache_get .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, None); } @@ -356,15 +338,14 @@ async fn test_unpinned_cache() { "cache_max_size": boc_max_size / 1024 + 1 } })); - let cache_set = client.wrap_async(cache_set, BocModule::api(), super::cache::cache_set_api()); - let cache_get = client.wrap_async(cache_get, BocModule::api(), super::cache::cache_get_api()); + let cache_set = client.wrap(cache_set, BocModule::api(), super::cache::cache_set_api()); + let cache_get = client.wrap(cache_get, BocModule::api(), super::cache::cache_get_api()); let ref1 = cache_set .call(ParamsOfBocCacheSet { boc: boc1.clone(), cache_type: BocCacheType::Unpinned, }) - .await .unwrap() .boc_ref; @@ -372,7 +353,6 @@ async fn test_unpinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc1.clone())); @@ -382,7 +362,6 @@ async fn test_unpinned_cache() { boc: boc2.clone(), cache_type: BocCacheType::Unpinned, }) - .await .unwrap() .boc_ref; @@ -390,7 +369,6 @@ async fn test_unpinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref1.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, None); @@ -398,7 +376,6 @@ async fn test_unpinned_cache() { .call(ParamsOfBocCacheGet { boc_ref: ref2.clone(), }) - .await .unwrap(); assert_eq!(boc.boc, Some(boc2.clone())); } @@ -942,7 +919,6 @@ async fn test_decode_tvc() { tvc: tvc_boc.to_string(), }, ) - .await .unwrap(); assert_eq!(expected, decoded); diff --git a/ton_client/src/boc/tvc.rs b/ton_client/src/boc/tvc.rs index aa9e96ccb..f1997c6d9 100644 --- a/ton_client/src/boc/tvc.rs +++ b/ton_client/src/boc/tvc.rs @@ -48,17 +48,15 @@ pub struct TvcV1 { pub description: Option, } -/// Decodes tvc according to the tvc spec. +/// Decodes tvc according to the tvc spec. /// Read more about tvc structure here https://github.com/tonlabs/ever-struct/blob/main/src/scheme/mod.rs#L30 #[api_function] -pub async fn decode_tvc( +pub fn decode_tvc( context: std::sync::Arc, params: ParamsOfDecodeTvc, ) -> ClientResult { - let tvc = deserialize_object_from_boc::(&context, ¶ms.tvc, "TVC") - .await? - .object; + let tvc = deserialize_object_from_boc::(&context, ¶ms.tvc, "TVC")?.object; let tvc = Tvc::V1(TvcV1 { code: tvc .code @@ -75,21 +73,17 @@ pub(crate) fn state_init_with_code(code: Cell) -> ClientResult { serialize_object_to_cell(&state_init, "state init") } -pub(crate) async fn resolve_state_init_cell( +pub(crate) fn resolve_state_init_cell( context: &ClientContext, tvc_or_state_init: &str, ) -> ClientResult { - if let Ok(tvc) = deserialize_object_from_boc::(context, tvc_or_state_init, "TVC").await { + if let Ok(tvc) = deserialize_object_from_boc::(context, tvc_or_state_init, "TVC") { if let Some(code) = tvc.object.code { state_init_with_code(code) } else { Err(crate::boc::Error::invalid_boc("TVC or StateInit"))? } } else { - Ok( - deserialize_cell_from_boc(context, tvc_or_state_init, "state init") - .await? - .1, - ) + Ok(deserialize_cell_from_boc(context, tvc_or_state_init, "state init")?.1) } } diff --git a/ton_client/src/client/tests.rs b/ton_client/src/client/tests.rs index e4015bf4f..e5c10136a 100644 --- a/ton_client/src/client/tests.rs +++ b/ton_client/src/client/tests.rs @@ -82,9 +82,14 @@ fn test_invalid_params_error_secret_stripped() { assert!(!error.message.contains(secret)); } +#[test] +fn test_sync_calls() { + +} + #[tokio::test] async fn test_memory_leak() { - for _ in 0..100 { + for _ in 0..1 { let config = json!({ "network": { "endpoints": TestClient::endpoints(), diff --git a/ton_client/src/debot/calltype.rs b/ton_client/src/debot/calltype.rs index c88ade46f..3d9cf58f5 100644 --- a/ton_client/src/debot/calltype.rs +++ b/ton_client/src/debot/calltype.rs @@ -3,10 +3,11 @@ use super::helpers::build_internal_message; use super::{BrowserCallbacks, DebotActivity, Spending, TonClient}; use crate::abi::Signer; use crate::boc::internal::{deserialize_object_from_base64, serialize_object_to_base64}; -use crate::boc::{get_boc_hash, parse_message, ParamsOfParse, ParamsOfGetBocHash}; +use crate::boc::{get_boc_hash, parse_message, ParamsOfGetBocHash, ParamsOfParse}; use crate::crypto::SigningBoxHandle; use crate::encoding::decode_abi_number; use crate::error::{ClientError, ClientResult}; +use crate::net::{query_transaction_tree, ParamsOfQueryTransactionTree}; use crate::processing::{ send_message, wait_for_transaction, ParamsOfSendMessage, ParamsOfWaitForTransaction, ProcessingEvent, @@ -17,7 +18,6 @@ use std::fmt::Display; use std::sync::Arc; use ton_block::{Message, MsgAddressExt, Serializable}; use ton_types::{BuilderData, IBitstring, SliceData}; -use crate::net::{query_transaction_tree, ParamsOfQueryTransactionTree}; const SUPPORTED_ABI_VERSION: u8 = 2; const ABI_2_3: u8 = 0x32; @@ -69,8 +69,7 @@ impl TryFrom for Metadata { let is_timestamp = slice.get_next_bit().map_err(msg_err)?; let is_expire = slice.get_next_bit().map_err(msg_err)?; let is_pubkey = slice.get_next_bit().map_err(msg_err)?; - let signing_box_handle = - match slice.get_next_bit().unwrap_or(false) { + let signing_box_handle = match slice.get_next_bit().unwrap_or(false) { true => Some(SigningBoxHandle(slice.get_next_u32().map_err(msg_err)?)), false => None, }; @@ -119,8 +118,7 @@ pub fn prepare_ext_in_message( let dst_addr: ton_block::MsgAddressInt = hdr.dst.clone(); let meta = Metadata::try_from(hdr.src.clone()).unwrap(); - let future = - decode_and_fix_ext_msg(msg, now_ms, &signer, true, &meta, &ton_client); + let future = decode_and_fix_ext_msg(msg, now_ms, &signer, true, &meta, &ton_client); let result = ton_client.env.block_on(future); @@ -135,7 +133,7 @@ async fn decode_and_fix_ext_msg( signer: &Signer, allow_no_signature: bool, meta: &Metadata, - ton: &TonClient + ton: &TonClient, ) -> ClientResult<(u32, Message)> { // find function id in message body: parse signature, pubkey and abi headers let mut message = msg.clone(); @@ -161,28 +159,28 @@ async fn decode_and_fix_ext_msg( // read `timestamp` header true => { let user_ts = in_body_slice.get_next_u64().map_err(msg_err)?; - Some(if meta.override_ts { user_ts } else {now_ms}) - }, + Some(if meta.override_ts { user_ts } else { now_ms }) + } false => None, }; let msg_exp = match meta.is_expire { // read `expire` header true => { let user_exp = in_body_slice.get_next_u32().map_err(msg_err)?; - Some(if meta.override_exp { - user_exp + Some(if meta.override_exp { + user_exp } else { ((now_ms / 1000) as u32) + ton.config.abi.message_expiration_timeout }) - }, + } false => None, }; // remember function id let func_id = in_body_slice.get_next_u32().map_err(msg_err)?; - // Rebuild msg body - insert correct `timestamp` and `expire` headers + // Rebuild msg body - insert correct `timestamp` and `expire` headers // if they are present, then sign body with signing box - + let mut new_body = BuilderData::new(); let pubkey = signer.resolve_public_key(ton.clone()).await?; if meta.is_pubkey { @@ -211,13 +209,22 @@ async fn decode_and_fix_ext_msg( match signer { Signer::SigningBox { handle: _ } => { let sdata = if meta.abi_ver >= ABI_2_3 { - let mut sdata = msg.dst().unwrap_or_default().write_to_new_cell().map_err(msg_err)?; + let mut sdata = msg + .dst() + .unwrap_or_default() + .write_to_new_cell() + .map_err(msg_err)?; sdata.append_builder(&new_body).map_err(msg_err)?; sdata } else { new_body.clone() }; - let hash = sdata.into_cell().map_err(msg_err)?.repr_hash().as_slice().to_vec(); + let hash = sdata + .into_cell() + .map_err(msg_err)? + .repr_hash() + .as_slice() + .to_vec(); let signature = signer.sign(ton.clone(), &hash).await?; if let Some(signature) = signature { signed_body @@ -227,14 +234,19 @@ async fn decode_and_fix_ext_msg( } else { signed_body.append_bit_zero().map_err(msg_err)?; } - }, + } _ => { signed_body.append_bit_zero().map_err(msg_err)?; } } signed_body.append_builder(&new_body).map_err(msg_err)?; - message.set_body(signed_body.into_cell().and_then(SliceData::load_cell).map_err(msg_err)?); + message.set_body( + signed_body + .into_cell() + .and_then(SliceData::load_cell) + .map_err(msg_err)?, + ); Ok((func_id, message)) } @@ -268,18 +280,30 @@ impl ContractCall { !local_run, signer, meta.signing_box_handle.clone(), - browser.clone() - ).await?; + browser.clone(), + ) + .await?; let dest_addr = msg .header() .get_dst_address() .map(|x| x.to_string()) .unwrap_or_default(); - Ok(Self { browser, ton, msg, signer, target_state, debot_addr, dest_addr, local_run, meta }) + Ok(Self { + browser, + ton, + msg, + signer, + target_state, + debot_addr, + dest_addr, + local_run, + meta, + }) } pub async fn execute(&self, wait_tx: bool) -> ClientResult { - let result = self.decode_and_fix_ext_msg() + let result = self + .decode_and_fix_ext_msg() .await .map_err(|e| Error::external_call_failed(e)); if let Err(e) = result { @@ -325,27 +349,39 @@ impl ContractCall { )); } let out_msg = messages.pop().unwrap(); - build_answer_msg(&out_msg, self.meta.answer_id, func_id, &self.dest_addr, &self.debot_addr) - .ok_or(Error::get_method_failed("failed to build answer message")) + build_answer_msg( + &out_msg, + self.meta.answer_id, + func_id, + &self.dest_addr, + &self.debot_addr, + ) + .ok_or(Error::get_method_failed("failed to build answer message")) } - async fn send_ext_msg(&self, func_id: u32, fixed_msg: String, wait_tx: bool) -> ClientResult { + async fn send_ext_msg( + &self, + func_id: u32, + fixed_msg: String, + wait_tx: bool, + ) -> ClientResult { let activity = emulate_transaction( self.ton.clone(), self.dest_addr.clone(), fixed_msg.clone(), self.target_state.clone(), self.signer.clone(), - ).await; + ) + .await; match activity { Ok(activity) => { if !self.browser.approve(activity).await? { return self.build_error_answer_msg(Error::operation_rejected()); } - }, + } Err(e) => { return self.build_error_answer_msg(e); - }, + } } let browser = self.browser.clone(); let callback = move |event| { @@ -376,8 +412,17 @@ impl ContractCall { callback.clone(), ) .await - .map(|e| { error!("{:?}", e); e })?; - let msg_id = get_boc_hash(self.ton.clone(), ParamsOfGetBocHash { boc: fixed_msg.clone() }).await?.hash; + .map(|e| { + error!("{:?}", e); + e + })?; + let msg_id = get_boc_hash( + self.ton.clone(), + ParamsOfGetBocHash { + boc: fixed_msg.clone(), + }, + )? + .hash; if wait_tx { let result = wait_for_transaction( self.ton.clone(), @@ -399,7 +444,8 @@ impl ContractCall { in_msg: msg_id, ..Default::default() }, - ).await; + ) + .await; if let Err(e) = result { return self.build_error_answer_msg(e); } @@ -409,7 +455,7 @@ impl ContractCall { self.meta.answer_id, func_id, &self.dest_addr, - &self.debot_addr + &self.debot_addr, ); if let Some(answer_msg) = res { return Ok(answer_msg); @@ -420,7 +466,10 @@ impl ContractCall { // answer message not found, build empty answer. let mut new_body = BuilderData::new(); new_body.append_u32(self.meta.answer_id).map_err(msg_err)?; - let new_body = new_body.into_cell().and_then(SliceData::load_cell).map_err(msg_err)?; + let new_body = new_body + .into_cell() + .and_then(SliceData::load_cell) + .map_err(msg_err)?; build_internal_message(&self.dest_addr, &self.debot_addr, new_body) } Err(e) => { @@ -435,7 +484,10 @@ impl ContractCall { .append_u32(self.meta.answer_id) .and_then(|b| b.append_raw(&msg_id, 256)) .map_err(msg_err)?; - let new_body = new_body.into_cell().and_then(SliceData::load_cell).map_err(msg_err)?; + let new_body = new_body + .into_cell() + .and_then(SliceData::load_cell) + .map_err(msg_err)?; build_internal_message(&self.dest_addr, &self.debot_addr, new_body) } } @@ -449,9 +501,11 @@ impl ContractCall { false, &self.meta, &self.ton, - ).await?; + ) + .await?; let (func_id, message) = result; - let msg = serialize_object_to_base64(&message, "message").map_err(|e| Error::invalid_msg(e))?; + let msg = + serialize_object_to_base64(&message, "message").map_err(|e| Error::invalid_msg(e))?; Ok((func_id, msg)) } @@ -473,7 +527,10 @@ fn build_onerror_body(onerror_id: u32, e: ClientError) -> ClientResult Option { - let out_message: Message = deserialize_object_from_base64(out_msg, "message").ok()?.object; + let out_message: Message = deserialize_object_from_base64(out_msg, "message") + .ok()? + .object; if out_message.is_internal() { return None; } @@ -496,9 +555,7 @@ fn build_answer_msg( if func_id != request_id { return None; } - new_body - .append_builder(&body_slice.as_builder()) - .ok()?; + new_body.append_builder(&body_slice.as_builder()).ok()?; } let new_body = new_body.into_cell().and_then(SliceData::load_cell).ok()?; @@ -509,15 +566,17 @@ async fn resolve_signer( sign: bool, signer: Signer, msg_signing_box: Option, - browser: Arc + browser: Arc, ) -> ClientResult { let new_signer = if sign { match signer { - Signer::SigningBox {handle: _} => signer, + Signer::SigningBox { handle: _ } => signer, _ => Signer::SigningBox { handle: match msg_signing_box { Some(signing_box_handle) => signing_box_handle, - None => browser.get_signing_box().await + None => browser + .get_signing_box() + .await .map_err(|e| Error::external_call_failed(e))?, }, }, @@ -566,7 +625,7 @@ async fn emulate_transaction( .unwrap_or(0); if exit_code != 0 { - let err = ClientError{ + let err = ClientError { code: 0, message: String::from(""), data: result.transaction, @@ -576,9 +635,7 @@ async fn emulate_transaction( let mut out = vec![]; for out_msg in result.out_messages { - let parsed = parse_message(client.clone(), ParamsOfParse { boc: out_msg }) - .await? - .parsed; + let parsed = parse_message(client.clone(), ParamsOfParse { boc: out_msg })?.parsed; let msg_type = parsed["msg_type"].as_u64().unwrap(); // if internal message if msg_type == 0 { @@ -592,7 +649,13 @@ async fn emulate_transaction( } let (signing_box_handle, signkey) = if let Signer::SigningBox { ref handle } = signer { - (handle.0, signer.resolve_public_key(client.clone()).await?.unwrap_or_default()) + ( + handle.0, + signer + .resolve_public_key(client.clone()) + .await? + .unwrap_or_default(), + ) } else { (0, String::new()) }; diff --git a/ton_client/src/debot/dengine.rs b/ton_client/src/debot/dengine.rs index ffe0ee449..23339c4b2 100644 --- a/ton_client/src/debot/dengine.rs +++ b/ton_client/src/debot/dengine.rs @@ -135,7 +135,6 @@ impl DEngine { async fn fetch_info(ton: TonClient, addr: String, state: String) -> Result { let dabi_version = fetch_target_abi_version(ton.clone(), state.clone()) - .await .map_err(|e| e.to_string())?; let abi = load_abi(DEBOT_ABI).unwrap(); let result = Self::run( @@ -609,7 +608,6 @@ impl DEngine { ..Default::default() }, ) - .await .map_err(|e| format!("failed to decode msg body: {}", e))?; debug!("calling {} at address {}", res.name, dest); diff --git a/ton_client/src/debot/dinterface.rs b/ton_client/src/debot/dinterface.rs index fc6441350..b5f0083ba 100644 --- a/ton_client/src/debot/dinterface.rs +++ b/ton_client/src/debot/dinterface.rs @@ -20,14 +20,14 @@ use crate::boc::internal::deserialize_cell_from_boc; use ton_sdk::AbiContract; use ton_abi::token::Detokenizer; -async fn decode_msg( +fn decode_msg( client: TonClient, msg_body: String, abi: Abi, ) -> ClientResult<(String, Value)> { let abi = abi.json_string()?; let abi = AbiContract::load(abi.as_bytes()).map_err(|e| Error::invalid_json(e))?; - let (_, body) = deserialize_cell_from_boc(&client, &msg_body, "message body").await?; + let (_, body) = deserialize_cell_from_boc(&client, &msg_body, "message body")?; let body = slice_from_cell(body)?; let input = abi.decode_input(body, true, false) .map_err(|e| Error::invalid_message_for_decode(e))?; @@ -93,7 +93,6 @@ pub trait DebotInterfaceExecutor { abi_version: &str, ) -> InterfaceResult { let parsed = parse_message(client.clone(), ParamsOfParse { boc: msg.clone() }) - .await .map_err(|e| format!("{}", e))?; let body = parsed.parsed["body"] @@ -105,7 +104,6 @@ pub trait DebotInterfaceExecutor { Some(object) => { let abi = object.get_target_abi(abi_version); let (func, args) = decode_msg(client.clone(), body, abi.clone()) - .await .map_err(|e| e.to_string())?; let (answer_id, mut ret_args) = object.call(&func, &args) .await @@ -224,4 +222,4 @@ pub fn get_array_strings(args: &Value, name: &str) -> Result, String strings.push(string.to_owned()); } Ok(strings) -} \ No newline at end of file +} diff --git a/ton_client/src/debot/info.rs b/ton_client/src/debot/info.rs index 172a2789d..988a4ccaa 100644 --- a/ton_client/src/debot/info.rs +++ b/ton_client/src/debot/info.rs @@ -58,18 +58,16 @@ pub(crate) fn parse_debot_info(value: Option) -> Result ClientResult { - let json_value = parse_account(ton.clone(), ParamsOfParse { boc: account_boc }) - .await? - .parsed; + let json_value = parse_account(ton.clone(), ParamsOfParse { boc: account_boc })?.parsed; let code = json_value["code"] .as_str() .ok_or(Error::debot_has_no_code())? .to_owned(); - let result = get_compiler_version(ton.clone(), ParamsOfGetCompilerVersion { code }).await; + let result = get_compiler_version(ton.clone(), ParamsOfGetCompilerVersion { code }); // If If DeBot's code does not contain version or SDK failed to read version, // then set empty string. diff --git a/ton_client/src/debot/msg_interface.rs b/ton_client/src/debot/msg_interface.rs index 9d20ab68d..259d4e291 100644 --- a/ton_client/src/debot/msg_interface.rs +++ b/ton_client/src/debot/msg_interface.rs @@ -80,7 +80,6 @@ impl MsgInterface { .map_err(|e| format!("{}", e))? .handle; let parsed_msg = parse_message(self.ton.clone(), ParamsOfParse { boc: message.clone() }) - .await .map_err(|e| format!("{}", e))? .parsed; let dest = parsed_msg["dst"].as_str().ok_or(format!("failed to parse dst address"))?.to_owned(); @@ -108,7 +107,6 @@ impl MsgInterface { ..Default::default() }, ) - .await .map_err(|e| format!("failed to decode message: {}", e))?; let abi_str = self.debot_abi.json_string().unwrap(); let contract = Contract::load(abi_str.as_bytes()).map_err(|e| format!("{}", e))?; @@ -122,7 +120,6 @@ impl MsgInterface { async fn send_async(&self, args: &Value) -> InterfaceResult { let message = get_arg(args, "message")?; let parsed_msg = parse_message(self.ton.clone(), ParamsOfParse { boc: message.clone() }) - .await .map_err(|e| format!("{}", e))? .parsed; let dest = parsed_msg["dst"].as_str().ok_or(format!("failed to parse dst address"))?.to_owned(); @@ -150,7 +147,6 @@ impl MsgInterface { ..Default::default() }, ) - .await .map_err(|e| format!("failed to decode message: {}", e))?; let abi_str = self.debot_abi.json_string().unwrap(); let contract = Contract::load(abi_str.as_bytes()).map_err(|e| format!("{}", e))?; diff --git a/ton_client/src/debot/routines.rs b/ton_client/src/debot/routines.rs index 419441bb7..4bbd7f11d 100644 --- a/ton_client/src/debot/routines.rs +++ b/ton_client/src/debot/routines.rs @@ -311,7 +311,6 @@ pub(super) async fn get_account( boc: get_arg(&accounts.swap_remove(0), "boc")?, }, ) - .await .map_err(|e| format!("failed to parse account from boc: {}", e))? .parsed; diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index 0cfd5097d..faa52a049 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -328,7 +328,7 @@ fn register_abi(handlers: &mut RuntimeHandlers) { crate::abi::encode_message_body, crate::abi::encode_message::encode_message_body_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::attach_signature_to_message_body, crate::abi::encode_message::attach_signature_to_message_body_api, ); @@ -340,15 +340,15 @@ fn register_abi(handlers: &mut RuntimeHandlers) { crate::abi::encode_internal_message, crate::abi::encode_message::encode_internal_message_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::attach_signature, crate::abi::encode_message::attach_signature_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::decode_message, crate::abi::decode_message::decode_message_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::decode_message_body, crate::abi::decode_message::decode_message_body_api, ); @@ -356,27 +356,27 @@ fn register_abi(handlers: &mut RuntimeHandlers) { crate::abi::encode_account, crate::abi::encode_account::encode_account_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::decode_account_data, crate::abi::decode_data::decode_account_data_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::update_initial_data, crate::abi::init_data::update_initial_data_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::encode_initial_data, crate::abi::init_data::encode_initial_data_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::decode_initial_data, crate::abi::init_data::decode_initial_data_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::decode_boc, crate::abi::decode_boc::decode_boc_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::encode_boc, crate::abi::encode_boc::encode_boc_api, ); @@ -404,65 +404,65 @@ fn register_boc(handlers: &mut RuntimeHandlers) { module.register_type::(); module.register_error_code::(); - module.register_async_fn(crate::boc::decode_tvc, crate::boc::tvc::decode_tvc_api); - module.register_async_fn( + module.register_sync_fn(crate::boc::decode_tvc, crate::boc::tvc::decode_tvc_api); + module.register_sync_fn( crate::boc::parse_message, crate::boc::parse::parse_message_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::parse_transaction, crate::boc::parse::parse_transaction_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::parse_account, crate::boc::parse::parse_account_api, ); - module.register_async_fn(crate::boc::parse_block, crate::boc::parse::parse_block_api); - module.register_async_fn( + module.register_sync_fn(crate::boc::parse_block, crate::boc::parse::parse_block_api); + module.register_sync_fn( crate::boc::parse_shardstate, crate::boc::parse::parse_shardstate_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::get_blockchain_config, crate::boc::blockchain_config::get_blockchain_config_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::get_boc_hash, crate::boc::common::get_boc_hash_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::get_boc_depth, crate::boc::common::get_boc_depth_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::get_code_from_tvc, crate::boc::state_init::get_code_from_tvc_api, ); - module.register_async_fn(crate::boc::cache_get, crate::boc::cache::cache_get_api); - module.register_async_fn(crate::boc::cache_set, crate::boc::cache::cache_set_api); - module.register_async_fn(crate::boc::cache_unpin, crate::boc::cache::cache_unpin_api); - module.register_async_fn(crate::boc::encode_boc, crate::boc::encode::encode_boc_api); - module.register_async_fn( + module.register_sync_fn(crate::boc::cache_get, crate::boc::cache::cache_get_api); + module.register_sync_fn(crate::boc::cache_set, crate::boc::cache::cache_set_api); + module.register_sync_fn(crate::boc::cache_unpin, crate::boc::cache::cache_unpin_api); + module.register_sync_fn(crate::boc::encode_boc, crate::boc::encode::encode_boc_api); + module.register_sync_fn( crate::boc::get_code_salt, crate::boc::state_init::get_code_salt_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::set_code_salt, crate::boc::state_init::set_code_salt_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::decode_state_init, crate::boc::state_init::decode_state_init_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::encode_state_init, crate::boc::state_init::encode_state_init_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::encode_external_in_message, crate::boc::encode_external_in_message::encode_external_in_message_api, ); - module.register_async_fn( + module.register_sync_fn( crate::boc::get_compiler_version, crate::boc::state_init::get_compiler_version_api, ); @@ -583,11 +583,11 @@ fn register_processing(handlers: &mut RuntimeHandlers) { module.register_type::(); module.register_type::(); - module.register_async_fn( + module.register_sync_fn( crate::processing::monitor_messages, crate::processing::monitor_messages_api, ); - module.register_async_fn( + module.register_sync_fn( crate::processing::get_monitor_info, crate::processing::get_monitor_info_api, ); @@ -595,7 +595,7 @@ fn register_processing(handlers: &mut RuntimeHandlers) { crate::processing::fetch_next_monitor_results, crate::processing::fetch_next_monitor_results_api, ); - module.register_async_fn( + module.register_sync_fn( crate::processing::cancel_monitor, crate::processing::cancel_monitor_api, ); diff --git a/ton_client/src/net/transaction_tree.rs b/ton_client/src/net/transaction_tree.rs index 373ecea4c..7df1a573c 100644 --- a/ton_client/src/net/transaction_tree.rs +++ b/ton_client/src/net/transaction_tree.rs @@ -58,7 +58,7 @@ pub struct ParamsOfQueryTransactionTree { /// Maximum transaction count to wait. If transaction tree contains more transaction then this /// parameter then only first `transaction_max_count` transaction are awaited and returned. - /// + /// /// Default value is 50. If `transaction_max_count` is set to 0 then no limitation on /// transaction count is used and all transaction are returned. pub transaction_max_count: Option, @@ -99,7 +99,7 @@ pub struct MessageNode { } impl MessageNode { - async fn from( + fn from( value: &Value, client: &Arc, abi_registry: &Option>, @@ -115,11 +115,11 @@ impl MessageNode { dst: get_string(value, "dst"), value: get_string(value, "value"), bounce: value["bounce"].as_bool().unwrap_or(false), - decoded_body: Self::try_decode_body(value, client, abi_registry).await, + decoded_body: Self::try_decode_body(value, client, abi_registry), }) } - async fn try_decode_body( + fn try_decode_body( message: &Value, client: &Arc, abi_registry: &Option>, @@ -137,9 +137,7 @@ impl MessageNode { is_internal, ..Default::default() }, - ) - .await - { + ) { return Some(result); } } @@ -316,16 +314,17 @@ pub async fn query_transaction_tree( let mut message_nodes = Vec::new(); let mut query_queue: Vec<(Option, String)> = vec![(None, params.in_msg.clone())]; let timeout = params.timeout.unwrap_or(DEFAULT_WAITING_TIMEOUT); - let transaction_max_count = params.transaction_max_count.unwrap_or(DEFAULT_TRANSACTION_MAX_COUNT) as usize; - while !query_queue.is_empty() && - (transaction_max_count == 0 || transaction_nodes.len() < transaction_max_count) + let transaction_max_count = params + .transaction_max_count + .unwrap_or(DEFAULT_TRANSACTION_MAX_COUNT) as usize; + while !query_queue.is_empty() + && (transaction_max_count == 0 || transaction_nodes.len() < transaction_max_count) { let (messages, src_transactions) = query_next_portion(server_link, timeout, &mut query_queue).await?; for message in messages { let message_node = - MessageNode::from(&message, &context, ¶ms.abi_registry, &src_transactions) - .await?; + MessageNode::from(&message, &context, ¶ms.abi_registry, &src_transactions)?; let transaction = &message["dst_transaction"]; if transaction.is_object() { let transaction_node = TransactionNode::from(&transaction, &message_node)?; diff --git a/ton_client/src/processing/fetching.rs b/ton_client/src/processing/fetching.rs index 1a7e1c40a..4bfe36f09 100644 --- a/ton_client/src/processing/fetching.rs +++ b/ton_client/src/processing/fetching.rs @@ -247,9 +247,9 @@ pub async fn fetch_transaction_result( } })?; - let (transaction, out_messages) = parse_transaction_boc(context.clone(), transaction_boc).await?; + let (transaction, out_messages) = parse_transaction_boc(context.clone(), transaction_boc)?; let abi_decoded = if let Some(abi) = abi { - Some(decode_output(context, abi, out_messages.clone()).await?) + Some(decode_output(context, abi, out_messages.clone())?) } else { None }; diff --git a/ton_client/src/processing/internal.rs b/ton_client/src/processing/internal.rs index a206e0239..71fd0f493 100644 --- a/ton_client/src/processing/internal.rs +++ b/ton_client/src/processing/internal.rs @@ -49,7 +49,7 @@ pub fn find_transactions( Ok(ids) } -pub(crate) async fn get_message_expiration_time( +pub(crate) fn get_message_expiration_time( context: Arc, abi: Option<&Abi>, message: &str, @@ -63,7 +63,6 @@ pub(crate) async fn get_message_expiration_time( ..Default::default() }, ) - .await .map(|x| x.header) .unwrap_or_default(), None => None, diff --git a/ton_client/src/processing/message_monitor.rs b/ton_client/src/processing/message_monitor.rs index 81cc3601a..2ab63d2c5 100644 --- a/ton_client/src/processing/message_monitor.rs +++ b/ton_client/src/processing/message_monitor.rs @@ -45,14 +45,12 @@ pub struct ParamsOfMonitorMessages { /// with specified unresolved messages. /// #[api_function] -pub async fn monitor_messages( +pub fn monitor_messages( context: Arc, params: ParamsOfMonitorMessages, ) -> ClientResult<()> { let monitor = context.message_monitor.clone(); - monitor - .monitor_messages(¶ms.queue, params.messages) - .await?; + monitor.monitor_messages(¶ms.queue, params.messages)?; Ok(()) } @@ -97,7 +95,7 @@ pub struct ParamsOfGetMonitorInfo { /// Returns summary information about current state of the specified monitoring queue. #[api_function] -pub async fn get_monitor_info( +pub fn get_monitor_info( context: Arc, params: ParamsOfGetMonitorInfo, ) -> ClientResult { @@ -113,7 +111,7 @@ pub struct ParamsOfCancelMonitor { /// Cancels all background activity and releases all allocated system resources /// for the specified monitoring queue. #[api_function] -pub async fn cancel_monitor( +pub fn cancel_monitor( context: Arc, params: ParamsOfCancelMonitor, ) -> ClientResult<()> { diff --git a/ton_client/src/processing/parsing.rs b/ton_client/src/processing/parsing.rs index 526ea55c7..ea28cb784 100644 --- a/ton_client/src/processing/parsing.rs +++ b/ton_client/src/processing/parsing.rs @@ -7,7 +7,7 @@ use crate::processing::types::DecodedOutput; use serde_json::Value; use std::sync::Arc; -pub(crate) async fn parse_transaction_boc( +pub(crate) fn parse_transaction_boc( context: Arc, transaction: TransactionBoc, ) -> ClientResult<(Value, Vec)> { @@ -21,14 +21,13 @@ pub(crate) async fn parse_transaction_boc( ParamsOfParse { boc: transaction.boc, }, - ) - .await? + )? .parsed, messages, )) } -pub(crate) async fn decode_output( +pub(crate) fn decode_output( context: &Arc, abi: &Abi, messages: Vec, @@ -43,7 +42,7 @@ pub(crate) async fn decode_output( abi: abi.clone(), ..Default::default() }, - ).await; + ); let decoded = match decode_result { Ok(decoded) => { if decoded.body_type == MessageBodyType::Output { diff --git a/ton_client/src/processing/send_message.rs b/ton_client/src/processing/send_message.rs index 9d5f18a05..0351f1274 100644 --- a/ton_client/src/processing/send_message.rs +++ b/ton_client/src/processing/send_message.rs @@ -74,14 +74,14 @@ struct SendingMessage { } impl SendingMessage { - async fn new( + fn new( context: &Arc, serialized: &str, abi: Option<&Abi>, ) -> ClientResult { // Check message let deserialized = - deserialize_object_from_boc::(&context, serialized, "message").await?; + deserialize_object_from_boc::(&context, serialized, "message")?; let id = deserialized.cell.repr_hash().as_hex_string(); let dst = deserialized .object @@ -89,7 +89,7 @@ impl SendingMessage { .ok_or(Error::message_has_not_destination_address())?; let message_expiration_time = - get_message_expiration_time(context.clone(), abi, &serialized).await?; + get_message_expiration_time(context.clone(), abi, &serialized)?; if let Some(message_expiration_time) = message_expiration_time { if message_expiration_time <= context.env.now_ms() { return Err(Error::message_already_expired()); @@ -222,7 +222,7 @@ pub async fn send_message + Send>( params: ParamsOfSendMessage, callback: impl Fn(ProcessingEvent) -> F + Send + Sync + Clone, ) -> ClientResult { - let message = SendingMessage::new(&context, ¶ms.message, params.abi.as_ref()).await?; + let message = SendingMessage::new(&context, ¶ms.message, params.abi.as_ref())?; let callback = if params.send_events { Some(callback) diff --git a/ton_client/src/processing/send_messages.rs b/ton_client/src/processing/send_messages.rs index 2810cf75d..3114aaf6a 100644 --- a/ton_client/src/processing/send_messages.rs +++ b/ton_client/src/processing/send_messages.rs @@ -83,8 +83,7 @@ pub async fn send_messages( if let Some(queue) = params.monitor_queue { context .message_monitor - .monitor_messages(&queue, messages.clone()) - .await?; + .monitor_messages(&queue, messages.clone())?; } Ok(ResultOfSendMessages { messages }) } diff --git a/ton_client/src/processing/tests.rs b/ton_client/src/processing/tests.rs index 0e5cbcd42..de7338de2 100644 --- a/ton_client/src/processing/tests.rs +++ b/ton_client/src/processing/tests.rs @@ -669,9 +669,7 @@ async fn test_deploy_from_tvc_v1() { let client = TestClient::new(); let (events_abi, events_state_init) = TestClient::package(EVENTS_OLD, Some(2)); let state_init_cell = - resolve_state_init_cell(&client.context(), &events_state_init.clone().unwrap()) - .await - .unwrap(); + resolve_state_init_cell(&client.context(), &events_state_init.clone().unwrap()).unwrap(); let state_init = deserialize_object_from_cell::(state_init_cell.clone(), "state init").unwrap(); let tvc = base64::encode( diff --git a/ton_client/src/processing/wait_for_transaction.rs b/ton_client/src/processing/wait_for_transaction.rs index b5ab987fa..988e76693 100644 --- a/ton_client/src/processing/wait_for_transaction.rs +++ b/ton_client/src/processing/wait_for_transaction.rs @@ -1,3 +1,4 @@ +use super::remp::{RempStatus, RempStatusData}; use crate::abi::Abi; use crate::boc::internal::deserialize_object_from_boc; use crate::client::ClientContext; @@ -6,14 +7,12 @@ use crate::net::{EndpointStat, ResultOfSubscription}; use crate::processing::internal::{get_message_expiration_time, resolve_error}; use crate::processing::{fetching, internal, Error}; use crate::processing::{ProcessingEvent, ResultOfProcessMessage}; +use futures::{FutureExt, StreamExt}; use std::convert::TryInto; use std::sync::Arc; -use futures::{FutureExt, StreamExt}; use tokio::sync::mpsc; use ton_block::{Message, MsgAddressInt}; -use super::remp::{RempStatus, RempStatusData}; - //--------------------------------------------------------------------------- wait_for_transaction #[derive(Serialize, Deserialize, ApiType, Default, Debug)] @@ -71,15 +70,15 @@ async fn wait_by_remp + Send>( let fallback_fut = async { notify.notified().await; wait_by_block_walking(context.clone(), ¶ms, callback.clone()).await - }.fuse(); + } + .fuse(); futures::pin_mut!(fallback_fut); // Prepare to wait - let message = - deserialize_object_from_boc::(&context, ¶ms.message, "message") - .await?; + let message = deserialize_object_from_boc::(&context, ¶ms.message, "message")?; let message_id = message.cell.repr_hash().as_hex_string(); - let message_dst = message.object + let message_dst = message + .object .dst() .ok_or(Error::message_has_not_destination_address())?; @@ -89,25 +88,30 @@ async fn wait_by_remp + Send>( let subscription_callback = move |event: ClientResult| { let sender = sender.clone(); async move { - let _ = sender.send(event.map(|mut result| result.result["rempReceipts"].take())).await; + let _ = sender + .send(event.map(|mut result| result.result["rempReceipts"].take())) + .await; } }; let subscription_result = crate::net::subscribe( context.clone(), crate::net::subscriptions::ParamsOfSubscribe { - subscription: format!(r#" + subscription: format!( + r#" subscription {{ rempReceipts(messageId: "{}") {{ messageId kind timestamp json }} }} "#, - message_id), + message_id + ), variables: None, }, - subscription_callback - ).await; + subscription_callback, + ) + .await; let subscription = match subscription_result { Ok(result) => Some(result), @@ -117,7 +121,8 @@ async fn wait_by_remp + Send>( error, message_id: message_id.clone(), message_dst: message_dst.to_string(), - }).await; + }) + .await; } notify.notify_one(); None @@ -176,10 +181,7 @@ async fn wait_by_remp + Send>( if let Some(result) = result { if let Some(subscription) = subscription { - let _ = crate::net::unsubscribe( - context.clone(), - subscription - ).await; + let _ = crate::net::unsubscribe(context.clone(), subscription).await; } return result; @@ -196,18 +198,26 @@ async fn process_remp_message + Send>( remp_message: ClientResult, ) -> ClientResult>> { let remp_message = remp_message?; - let status: RempStatus = serde_json::from_value(remp_message) - .map_err(|err| Error::invalid_remp_status(format!("can not parse REMP status message: {}", err)))?; + let status: RempStatus = serde_json::from_value(remp_message).map_err(|err| { + Error::invalid_remp_status(format!("can not parse REMP status message: {}", err)) + })?; match status { - RempStatus::RejectedByFullnode(data) => { - Ok(Some(process_rejected_status(context.clone(), params, &message_dst, data).await)) - }, - RempStatus::Finalized(data) => { - Ok(Some(Ok(process_finalized_status(context.clone(), params, message_id, &message_dst, data).await?))) - }, + RempStatus::RejectedByFullnode(data) => Ok(Some( + process_rejected_status(context.clone(), params, &message_dst, data).await, + )), + RempStatus::Finalized(data) => Ok(Some(Ok(process_finalized_status( + context.clone(), + params, + message_id, + &message_dst, + data, + ) + .await?))), _ => { - if params.send_events { callback(status.into_event(message_dst.to_string())).await; } + if params.send_events { + callback(status.into_event(message_dst.to_string())).await; + } Ok(None) } } @@ -220,8 +230,8 @@ async fn process_rejected_status( data: RempStatusData, ) -> ClientResult { let message_expiration_time = - get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message).await? - .unwrap_or_else(|| context.env.now_ms()); + get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message)? + .unwrap_or_else(|| context.env.now_ms()); let error = data.json["error"].as_str().unwrap_or("unknown error"); @@ -248,8 +258,8 @@ async fn process_finalized_status( data: RempStatusData, ) -> ClientResult { let message_expiration_time = - get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message).await? - .unwrap_or_else(|| context.env.now_ms()); + get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message)? + .unwrap_or_else(|| context.env.now_ms()); let block_id = data.json["block_id"] .as_str() @@ -258,19 +268,19 @@ async fn process_finalized_status( // Transaction has been found. // Let's fetch other stuff. let result = fetching::fetch_transaction_result( - &context, - block_id, - message_id, - ¶ms.message, - None, - ¶ms.abi, - message_dst.clone(), - (message_expiration_time / 1000) as u32, - (context.env.now_ms() / 1000) as u32, - ) - .await - .add_network_url_from_context(&context) - .await; + &context, + block_id, + message_id, + ¶ms.message, + None, + ¶ms.abi, + message_dst.clone(), + (message_expiration_time / 1000) as u32, + (context.env.now_ms() / 1000) as u32, + ) + .await + .add_network_url_from_context(&context) + .await; if result.is_ok() { if let Some(endpoints) = ¶ms.sending_endpoints { context @@ -290,17 +300,16 @@ async fn wait_by_block_walking + Send>( let net = context.get_server_link()?; // Prepare to wait - let message = - deserialize_object_from_boc::(&context, ¶ms.message, "message") - .await?; + let message = deserialize_object_from_boc::(&context, ¶ms.message, "message")?; let message_id = message.cell.repr_hash().as_hex_string(); let address = message .object - .dst_ref().cloned() + .dst_ref() + .cloned() .ok_or(Error::message_has_not_destination_address())?; let message_expiration_time = - get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message).await?; + get_message_expiration_time(context.clone(), params.abi.as_ref(), ¶ms.message)?; let processing_timeout = net.config().message_processing_timeout; let max_block_time = message_expiration_time.unwrap_or(context.env.now_ms() + processing_timeout as u64); @@ -313,10 +322,10 @@ async fn wait_by_block_walking + Send>( // Block walking loop loop { let now = context.env.now_ms(); - let fetch_block_timeout = - (std::cmp::max(max_block_time, now) - now + processing_timeout as u64) - .try_into() - .unwrap_or(u32::MAX); + let fetch_block_timeout = (std::cmp::max(max_block_time, now) - now + + processing_timeout as u64) + .try_into() + .unwrap_or(u32::MAX); log::debug!("fetch_block_timeout {}", fetch_block_timeout); let block = fetching::fetch_next_shard_block( diff --git a/ton_client/src/tvm/run_get.rs b/ton_client/src/tvm/run_get.rs index d227042e8..24caf208a 100644 --- a/ton_client/src/tvm/run_get.rs +++ b/ton_client/src/tvm/run_get.rs @@ -60,7 +60,7 @@ pub async fn run_get( params: ParamsOfRunGet, ) -> ClientResult { let mut account: ton_block::Account = - deserialize_object_from_boc(&context, ¶ms.account, "account").await?.object; + deserialize_object_from_boc(&context, ¶ms.account, "account")?.object; let options = ResolvedExecutionOptions::from_options(&context, params.execution_options).await?; if account.is_none() { diff --git a/ton_client/src/tvm/run_message.rs b/ton_client/src/tvm/run_message.rs index fdeee9c00..ec6765268 100644 --- a/ton_client/src/tvm/run_message.rs +++ b/ton_client/src/tvm/run_message.rs @@ -14,21 +14,23 @@ use super::stack::serialize_item; use super::types::{ExecutionOptions, ResolvedExecutionOptions}; -use crate::{abi::Abi, boc::BocCacheType}; use crate::boc::internal::{ deserialize_cell_from_boc, deserialize_object_from_boc, deserialize_object_from_cell, serialize_cell_to_boc, serialize_object_to_base64, serialize_object_to_boc, - serialize_object_to_cell + serialize_object_to_cell, }; use crate::client::ClientContext; use crate::error::ClientResult; use crate::processing::{parsing::decode_output, DecodedOutput}; use crate::tvm::{check_transaction::calc_transaction_fees, Error}; +use crate::{abi::Abi, boc::BocCacheType}; use serde_json::Value; use std::convert::TryFrom; use std::sync::{atomic::AtomicU64, Arc}; -use ton_block::{Account, Message, Serializable, MsgAddressInt, CurrencyCollection, Transaction}; -use ton_executor::{ExecutorError, ExecuteParams, OrdinaryTransactionExecutor, TransactionExecutor}; +use ton_block::{Account, CurrencyCollection, Message, MsgAddressInt, Serializable, Transaction}; +use ton_executor::{ + ExecuteParams, ExecutorError, OrdinaryTransactionExecutor, TransactionExecutor, +}; use ton_sdk::TransactionFees; use ton_types::{Cell, UInt256}; @@ -60,7 +62,7 @@ impl Default for AccountForExecutor { const UNLIMITED_BALANCE: u64 = u64::MAX; impl AccountForExecutor { - pub async fn get_account( + pub fn get_account( &self, context: &Arc, address: MsgAddressInt, @@ -82,12 +84,14 @@ impl AccountForExecutor { } => { if unlimited_balance.unwrap_or_default() { let mut account: Account = - deserialize_object_from_boc(context, &boc, "account").await?.object; + deserialize_object_from_boc(context, &boc, "account")?.object; let original_balance = account .balance() - .ok_or_else(|| Error::invalid_account_boc( - "can not set unlimited balance for non existed account", - ))? + .ok_or_else(|| { + Error::invalid_account_boc( + "can not set unlimited balance for non existed account", + ) + })? .clone(); let mut balance = original_balance.clone(); balance.grams = UNLIMITED_BALANCE.into(); @@ -95,7 +99,7 @@ impl AccountForExecutor { let account = serialize_object_to_cell(&account, "account")?; Ok((account, Some(original_balance))) } else { - let (_, account) = deserialize_cell_from_boc(context, &boc, "account").await?; + let (_, account) = deserialize_cell_from_boc(context, &boc, "account")?; Ok((account, None)) } } @@ -147,7 +151,7 @@ pub struct ParamsOfRunTvm { /// Cache type to put the result. The BOC itself returned if no cache type provided pub boc_cache: Option, /// Return updated account flag. Empty string is returned if the flag is `false` - pub return_updated_account: Option + pub return_updated_account: Option, } #[derive(Serialize, Deserialize, ApiType, Default, Debug, PartialEq, Clone)] @@ -187,7 +191,7 @@ pub struct ResultOfRunTvm { pub account: String, } -async fn parse_transaction( +fn parse_transaction( context: &Arc, transaction: &Transaction, ) -> ClientResult { @@ -196,8 +200,7 @@ async fn parse_transaction( crate::boc::ParamsOfParse { boc: serialize_object_to_base64(transaction, "transaction")?, }, - ) - .await? + )? .parsed) } @@ -240,11 +243,7 @@ pub async fn run_executor( context: Arc, params: ParamsOfRunExecutor, ) -> ClientResult { - run_executor_internal( - context, - params, - true, - ).await + run_executor_internal(context, params, true).await } pub async fn run_executor_internal( @@ -252,10 +251,15 @@ pub async fn run_executor_internal( params: ParamsOfRunExecutor, show_tips_on_error: bool, ) -> ClientResult { - let message = deserialize_object_from_boc::(&context, ¶ms.message, "message").await?.object; - let msg_address = message.dst_ref().ok_or_else(|| Error::invalid_message_type())?.clone(); - let (account, _) = params.account.get_account(&context, msg_address.clone()).await?; - let options = ResolvedExecutionOptions::from_options(&context, params.execution_options).await?; + let message = + deserialize_object_from_boc::(&context, ¶ms.message, "message")?.object; + let msg_address = message + .dst_ref() + .ok_or_else(|| Error::invalid_message_type())? + .clone(); + let (account, _) = params.account.get_account(&context, msg_address.clone())?; + let options = + ResolvedExecutionOptions::from_options(&context, params.execution_options).await?; let account_copy = account.clone(); let contract_info = move || async move { @@ -267,14 +271,14 @@ pub async fn run_executor_internal( } }; - let (transaction, modified_account) = - call_executor( - account.clone(), - message, - options, - contract_info.clone(), - show_tips_on_error, - ).await?; + let (transaction, modified_account) = call_executor( + account.clone(), + message, + options, + contract_info.clone(), + show_tips_on_error, + ) + .await?; let sdk_transaction = ton_sdk::Transaction::try_from(&transaction) .map_err(|err| Error::can_not_read_transaction(err))?; @@ -299,27 +303,26 @@ pub async fn run_executor_internal( // TODO decode Message object without converting to string let decoded = if let Some(abi) = params.abi.as_ref() { - Some(decode_output(&context, abi, out_messages.clone()).await?) + Some(decode_output(&context, abi, out_messages.clone())?) } else { None }; let account = if params.return_updated_account.unwrap_or_default() { - serialize_cell_to_boc(&context, modified_account, "account", params.boc_cache).await? + serialize_cell_to_boc(&context, modified_account, "account", params.boc_cache)? } else { String::new() }; Ok(ResultOfRunExecutor { out_messages, - transaction: parse_transaction(&context, &transaction).await?, + transaction: parse_transaction(&context, &transaction)?, account, decoded, fees, }) } - /// Executes get-methods of ABI-compatible contracts /// /// Performs only a part of compute phase of transaction execution @@ -339,29 +342,36 @@ pub async fn run_tvm( context: Arc, params: ParamsOfRunTvm, ) -> ClientResult { - let mut account = deserialize_object_from_boc::(&context, ¶ms.account, "account").await?; - let message = deserialize_object_from_boc::(&context, ¶ms.message, "message").await?.object; - let options = ResolvedExecutionOptions::from_options(&context, params.execution_options).await?; + let mut account = deserialize_object_from_boc::(&context, ¶ms.account, "account")?; + let message = + deserialize_object_from_boc::(&context, ¶ms.message, "message")?.object; + let options = + ResolvedExecutionOptions::from_options(&context, params.execution_options).await?; if account.object.is_none() { - return Err(Error::invalid_account_boc("Account is None")) + return Err(Error::invalid_account_boc("Account is None")); } let messages = super::call_tvm::call_tvm_msg(&mut account.object, options, &message)?; let mut out_messages = vec![]; for message in messages { - out_messages.push(serialize_object_to_boc(&context, &message, "message", params.boc_cache.clone()).await?); + out_messages.push(serialize_object_to_boc( + &context, + &message, + "message", + params.boc_cache.clone(), + )?); } // TODO decode Message object without converting to string let decoded = if let Some(abi) = params.abi.as_ref() { - Some(decode_output(&context, abi, out_messages.clone()).await?) + Some(decode_output(&context, abi, out_messages.clone())?) } else { None }; let account = if params.return_updated_account.unwrap_or_default() { - serialize_object_to_boc(&context, &account.object, "account", params.boc_cache).await? + serialize_object_to_boc(&context, &account.object, "account", params.boc_cache)? } else { String::new() }; @@ -384,8 +394,7 @@ where F: futures::Future>, { let executor = OrdinaryTransactionExecutor::new( - Arc::try_unwrap(options.blockchain_config) - .unwrap_or_else(|arc| arc.as_ref().clone()) + Arc::try_unwrap(options.blockchain_config).unwrap_or_else(|arc| arc.as_ref().clone()), ); let params = ExecuteParams { block_unixtime: options.block_time, @@ -396,39 +405,40 @@ where signature_id: options.signature_id, ..ExecuteParams::default() }; - let transaction = match executor.execute_with_libs_and_params(Some(&msg), &mut account_root, params) { - Ok(transaction) => transaction, - Err(err) => { - let err_message = err.to_string(); - let err = match contract_info().await { - Ok((address, balance)) => match &err.downcast_ref::() { - Some(ExecutorError::NoAcceptError(code, exit_arg)) => { - let exit_arg = exit_arg - .as_ref() - .map(|item| serialize_item(item)) - .transpose()?; - Error::tvm_execution_failed( - err_message, - *code, - exit_arg, - &address, - None, - show_tips_on_error, - ) - } - Some(ExecutorError::NoFundsToImportMsg) => { - Error::low_balance(&address, balance) - } - Some(ExecutorError::ExtMsgComputeSkipped(reason)) => { - Error::tvm_execution_skipped(reason, &address, balance) - } - _ => Error::unknown_execution_error(err), - }, - Err(err) => err, - }; - return Err(err); - } - }; + let transaction = + match executor.execute_with_libs_and_params(Some(&msg), &mut account_root, params) { + Ok(transaction) => transaction, + Err(err) => { + let err_message = err.to_string(); + let err = match contract_info().await { + Ok((address, balance)) => match &err.downcast_ref::() { + Some(ExecutorError::NoAcceptError(code, exit_arg)) => { + let exit_arg = exit_arg + .as_ref() + .map(|item| serialize_item(item)) + .transpose()?; + Error::tvm_execution_failed( + err_message, + *code, + exit_arg, + &address, + None, + show_tips_on_error, + ) + } + Some(ExecutorError::NoFundsToImportMsg) => { + Error::low_balance(&address, balance) + } + Some(ExecutorError::ExtMsgComputeSkipped(reason)) => { + Error::tvm_execution_skipped(reason, &address, balance) + } + _ => Error::unknown_execution_error(err), + }, + Err(err) => err, + }; + return Err(err); + } + }; Ok((transaction, account_root)) } diff --git a/ton_client/src/tvm/types.rs b/ton_client/src/tvm/types.rs index a33d4e315..6abee141d 100644 --- a/ton_client/src/tvm/types.rs +++ b/ton_client/src/tvm/types.rs @@ -48,8 +48,8 @@ pub(crate) struct ResolvedExecutionOptions { pub behavior_modifiers: BehaviorModifiers, } -pub(crate) async fn blockchain_config_from_boc(context: &ClientContext, b64: &str) -> ClientResult { - let config_params = deserialize_object_from_boc(context, b64, "blockchain config").await?; +pub(crate) fn blockchain_config_from_boc(context: &ClientContext, b64: &str) -> ClientResult { + let config_params = deserialize_object_from_boc(context, b64, "blockchain config")?; BlockchainConfig::with_config(config_params.object) .map_err(|err| Error::can_not_read_blockchain_config(err)) } @@ -95,14 +95,14 @@ pub(crate) async fn resolve_network_params( match (provided_config, provided_global_id.or(context.config.network.signature_id)) { (Some(config), Some(global_id)) => { Ok(NetworkParams { - blockchain_config: Arc::new(blockchain_config_from_boc(context, &config).await?), + blockchain_config: Arc::new(blockchain_config_from_boc(context, &config)?), global_id, }) }, (Some(config), None) => { let default = get_default_params(context).await?; Ok(NetworkParams { - blockchain_config: Arc::new(blockchain_config_from_boc(context, &config).await?), + blockchain_config: Arc::new(blockchain_config_from_boc(context, &config)?), global_id: default.global_id, }) }, diff --git a/ton_client/src/utils/calc_storage_fee.rs b/ton_client/src/utils/calc_storage_fee.rs index fa35ed67a..65816471c 100644 --- a/ton_client/src/utils/calc_storage_fee.rs +++ b/ton_client/src/utils/calc_storage_fee.rs @@ -19,16 +19,16 @@ use std::sync::Arc; #[derive(Serialize, Deserialize, ApiType, Default, Debug)] pub struct ParamsOfCalcStorageFee { - // Account BOC or BOC cache reference - pub account: String, - // Time period in seconds - pub period: u32, + // Account BOC or BOC cache reference + pub account: String, + // Time period in seconds + pub period: u32, } #[derive(Serialize, Deserialize, ApiType, Default, Debug)] pub struct ResultOfCalcStorageFee { - // Storage fee over a period of time in nanotokens - pub fee: String + // Storage fee over a period of time in nanotokens + pub fee: String, } /// Calculates storage fee for an account over a specified time period @@ -37,28 +37,37 @@ pub async fn calc_storage_fee( context: Arc, params: ParamsOfCalcStorageFee, ) -> ClientResult { - let account = deserialize_object_from_boc::( - &context, ¶ms.account, "account" - ) - .await? - .object; + let account = + deserialize_object_from_boc::(&context, ¶ms.account, "account")? + .object; - let storage = account.storage_info().ok_or(Error::invalid_account_boc("Account is None"))?; - let addr = account.get_addr().ok_or(Error::invalid_account_boc("Account is None"))?; - let config = crate::net::network_params::get_default_params(&context).await?.blockchain_config; + let storage = account + .storage_info() + .ok_or(Error::invalid_account_boc("Account is None"))?; + let addr = account + .get_addr() + .ok_or(Error::invalid_account_boc("Account is None"))?; + let config = crate::net::network_params::get_default_params(&context) + .await? + .blockchain_config; if storage.last_paid() == 0 { - return Err(Error::invalid_account_boc("Account `last_paid` field is not initialized")); + return Err(Error::invalid_account_boc( + "Account `last_paid` field is not initialized", + )); } - let fee = config.calc_storage_fee( - storage, - addr.is_masterchain(), - storage.last_paid() + params.period, - ) - .map_err(|err| Error::invalid_account_boc(format!("can not calculate storage fee: {}", err)))?; + let fee = config + .calc_storage_fee( + storage, + addr.is_masterchain(), + storage.last_paid() + params.period, + ) + .map_err(|err| { + Error::invalid_account_boc(format!("can not calculate storage fee: {}", err)) + })?; Ok(ResultOfCalcStorageFee { - fee: format!("{}", fee.as_u128()) + fee: format!("{}", fee.as_u128()), }) -} \ No newline at end of file +} diff --git a/ton_client_processing/src/message_monitor/monitor.rs b/ton_client_processing/src/message_monitor/monitor.rs index 6204044b8..6f3f31a68 100644 --- a/ton_client_processing/src/message_monitor/monitor.rs +++ b/ton_client_processing/src/message_monitor/monitor.rs @@ -53,12 +53,12 @@ impl MessageMonitor, ) -> crate::error::Result<()> { - self.state.monitor_messages(queue, messages).await + self.state.monitor_messages(queue, messages) } pub async fn fetch_next_monitor_results( @@ -92,7 +92,7 @@ impl MonitorState { } } - async fn monitor_messages( + fn monitor_messages( self: &Arc, queue: &str, messages: Vec, From 3b4956ce900eb369abe41576903dfdab5d7fcc7a Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Thu, 29 Jun 2023 22:28:16 +0300 Subject: [PATCH 02/11] NEW: Ability to call async functions via `tc_request_sync`. NEW In rust API, some functions become sync (see CHANGELOG.md). NEW: Code generator for `modules.ts` produces `_sync` wrapper for all API functions. --- CHANGELOG.md | 17 ++++++ ton_client/src/abi/encode_message.rs | 2 +- ton_client/src/json_interface/interop.rs | 2 +- ton_client/src/json_interface/modules.rs | 2 +- ton_client/src/json_interface/runtime.rs | 73 +++++++++++++++++++++++- ton_client/src/net/tests.rs | 29 ++++++++++ tools/ts-code.ts | 43 ++++++++++++-- 7 files changed, 156 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4071702aa..b28aaee9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,23 @@ All notable changes to this project will be documented in this file. +## [1.43.3] – 2023-06-24 + +### New + +- Ability to call async functions via `tc_request_sync`. +- In rust API, the following functions become sync (slight breaking): + `abi::encode_internal_message`, `abi::attach_signature_to_message_body`, `abi::attach_signature`, + `abi::decode_message`, `abi::decode_message_body`, `abi::decode_account_data`, + `abi::update_initial_data`, `abi::encode_initial_data`, `abi::decode_initial_data`, + `abi::decode_boc`, `abi::encode_boc`, `boc::decode_tvc`, `boc::parse_message`, `boc::parse_transaction`, + `boc::parse_account`, `boc::parse_block`, `boc::parse_shardstate`, `boc::get_blockchain_config`, + `boc::get_boc_hash`, `boc::get_code_from_tvc`, `boc::cache_get`, `boc::cache_set`, `boc::cache_unpin`, + `boc::encode_boc`, `boc::get_code_salt`, `boc::set_code_salt`, `boc::decode_state_init`, `boc::encode_state_init`, + `boc::encode_external_in_message`, `boc::get_compiler_version`, `processing::monitor_messages`, + `processing::get_monitor_info`, `processing::cancel_monitor` +- Code generator for `modules.ts` produces `_sync` wrapper for all API functions. + ## [1.43.3] – 2023-06-24 ### Fixed diff --git a/ton_client/src/abi/encode_message.rs b/ton_client/src/abi/encode_message.rs index 091301df5..3f3e0e202 100644 --- a/ton_client/src/abi/encode_message.rs +++ b/ton_client/src/abi/encode_message.rs @@ -618,7 +618,7 @@ pub struct ResultOfEncodeInternalMessage { /// 2. Public key, specified in TVM file. #[api_function] -pub async fn encode_internal_message( +pub fn encode_internal_message( context: Arc, params: ParamsOfEncodeInternalMessage, ) -> ClientResult { diff --git a/ton_client/src/json_interface/interop.rs b/ton_client/src/json_interface/interop.rs index 74e092917..73235c23d 100644 --- a/ton_client/src/json_interface/interop.rs +++ b/ton_client/src/json_interface/interop.rs @@ -35,7 +35,7 @@ pub enum ResponseType { Error = 1, Nop = 2, AppRequest = 3, - AppNotify = 4, + AppNotify = 4, Custom = 100, } diff --git a/ton_client/src/json_interface/modules.rs b/ton_client/src/json_interface/modules.rs index faa52a049..9e5d11a22 100644 --- a/ton_client/src/json_interface/modules.rs +++ b/ton_client/src/json_interface/modules.rs @@ -336,7 +336,7 @@ fn register_abi(handlers: &mut RuntimeHandlers) { crate::abi::encode_message, crate::abi::encode_message::encode_message_api, ); - module.register_async_fn( + module.register_sync_fn( crate::abi::encode_internal_message, crate::abi::encode_message::encode_internal_message_api, ); diff --git a/ton_client/src/json_interface/runtime.rs b/ton_client/src/json_interface/runtime.rs index 45802b6cc..f815b42fc 100644 --- a/ton_client/src/json_interface/runtime.rs +++ b/ton_client/src/json_interface/runtime.rs @@ -15,10 +15,11 @@ use super::modules::register_modules; use super::request::Request; use crate::client::{ClientConfig, ClientContext, Error}; -use crate::error::ClientResult; -use crate::ContextHandle; +use crate::error::{ClientError, ClientResult}; +use crate::{ContextHandle, ResponseType}; use api_info::{Module, API}; use std::collections::HashMap; +use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex, MutexGuard}; pub(crate) trait SyncHandler { @@ -88,6 +89,72 @@ lazy_static! { pub struct Runtime; +// Used as a `request_ptr` in case when async handler invoker via `dispatch_sync` +struct AsyncAsSyncHandler { + // Used to send async result to the waiting sync handler. + result_sender: Sender>, + // Indicates that async result (success or error) is already sent to the sync handler + // and async handler should ignore all following responses. + result_sent: bool, +} + +impl AsyncAsSyncHandler { + fn dispatch( + context: Arc, + function_name: String, + params_json: String, + ) -> ClientResult { + let (result_sender, result_receiver) = std::sync::mpsc::channel::>(); + // Create state, unbox it into raw pointer and send to the `dispatch_sync` + let handler = Box::into_raw(Box::new(Self { + result_sender, + result_sent: false, + })); + Runtime::dispatch_async( + context, + function_name, + params_json, + Request::new_with_ptr(handler as *const (), Self::response_handler), + ); + let result = result_receiver + .recv() + .unwrap_or_else(|err| Err(Error::can_not_receive_request_result(err))); + result + } + + fn handle_response(&mut self, params_json: String, response_type: u32) { + if self.result_sent { + return; + } + let result = if response_type == ResponseType::Success as u32 { + Ok(params_json) + } else if response_type == ResponseType::Error as u32 { + Err(serde_json::from_str::(¶ms_json) + .unwrap_or_else(|err| Error::callback_params_cant_be_converted_to_json(err))) + } else { + return; + }; + let _ = self.result_sender.send(result); + self.result_sent = true; + } + + fn response_handler( + request_ptr: *const (), + params_json: String, + response_type: u32, + finished: bool, + ) { + let handler = request_ptr as *mut Self; + if let Some(handler) = unsafe { handler.as_mut() } { + handler.handle_response(params_json, response_type); + } + if finished { + // Box handler from raw pointer and drop it + let _ = unsafe { Box::from_raw(handler) }; + } + } +} + impl Runtime { fn handlers() -> &'static RuntimeHandlers { &HANDLERS @@ -104,7 +171,7 @@ impl Runtime { ) -> ClientResult { match Self::handlers().sync_handlers.get(&function_name) { Some(handler) => handler.handle(context, params_json.as_str()), - None => Err(Error::unknown_function(&function_name)), + None => AsyncAsSyncHandler::dispatch(context, function_name, params_json), } } diff --git a/ton_client/src/net/tests.rs b/ton_client/src/net/tests.rs index 11b2f91a2..56626eaaf 100644 --- a/ton_client/src/net/tests.rs +++ b/ton_client/src/net/tests.rs @@ -260,6 +260,35 @@ async fn query() { assert_eq!(version.split(".").count(), 3); } +#[test] +fn query_sync() { + let client = TestClient::new(); + + let info: ResultOfQuery = client + .request( + "net.query", + ParamsOfQuery { + query: "query{info{version}}".to_owned(), + variables: None, + }, + ) + .unwrap(); + + let version = info.result["data"]["info"]["version"].as_str().unwrap(); + assert_eq!(version.split(".").count(), 3); + + let result: ClientResult = client + .request( + "net.query", + ParamsOfQuery { + query: "query{info111{version}}".to_owned(), + variables: None, + }, + ); + + assert!(result.is_err()); +} + #[tokio::test(flavor = "multi_thread", worker_threads = 2)] async fn block_signatures() { let client = TestClient::new(); diff --git a/tools/ts-code.ts b/tools/ts-code.ts index 532400613..07dfc6087 100644 --- a/tools/ts-code.ts +++ b/tools/ts-code.ts @@ -36,6 +36,10 @@ interface IClient { functionParams?: any, responseHandler?: ResponseHandler ): Promise; + requestSync( + functionName: string, + functionParams?: any, + ): any; resolve_app_request(app_request_id: number | null, result: any): Promise; reject_app_request(app_request_id: number | null, error: any): Promise; } @@ -158,15 +162,20 @@ export class ${Code.upperFirst(module.name)}Module { `; for (const func of module.functions) { - ts += jsDocStart(func, INDENT); const info = this.getFunctionInfo(func); - if (info.params) { - ts += jsDoc("", INDENT); - ts += jsDoc(`@param {${getRefName(info.params)}} ${info.params.name}`, INDENT); + const funcDoc = () => { + ts += jsDocStart(func, INDENT); + if (info.params) { + ts += jsDoc("", INDENT); + ts += jsDoc(`@param {${getRefName(info.params)}} ${info.params.name}`, INDENT); + } + ts += jsDoc(`@returns ${getRefName(func.result)}`, INDENT); + ts += jsDocEnd(INDENT); } - ts += jsDoc(`@returns ${getRefName(func.result)}`, INDENT); - ts += jsDocEnd(INDENT); + funcDoc() ts += this.functionImpl(func); + funcDoc() + ts += this.syncFunctionImpl(func); } ts += "}\n\n"; @@ -289,6 +298,14 @@ export class ${Code.upperFirst(module.name)}Module { return decls; } + syncParamsDecls(paramsInfo: ApiFunctionInfo): string[] { + const decls: string[] = []; + if (paramsInfo.params) { + decls.push(`${paramsInfo.params.name}: ${this.type(paramsInfo.params, "")}`); + } + return decls; + } + functionInterface(func: ApiFunction): string { const paramsInfo = this.getFunctionInfo(func); const paramsDecls = this.paramsDecls(paramsInfo); @@ -378,6 +395,20 @@ async function dispatch${obj.name}(obj: ${obj.name}, params: ParamsOf${obj.name} }\n`; } + syncFunctionImpl(func: ApiFunction): string { + const paramsInfo = this.getFunctionInfo(func); + const paramsDecl = this.syncParamsDecls(paramsInfo).map(p => `${p}`).join(", "); + const calls = [`'${func.module.name}.${func.name}'`]; + if (paramsInfo.params) { + calls.push(`${paramsInfo.params.name}`); + } + const returnStatement = func.result.type !== ApiTypeIs.None ? "return " : ""; + return ` + ${func.name}_sync(${paramsDecl}): ${this.type(func.result, "")} { + ${returnStatement}this.client.requestSync(${calls.join(", ")}); + }\n`; + } + modules(): string { return ` ${MODULES_HEADER} From a4fc377857e9e7273552e319198f1e126b81ca0d Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Fri, 30 Jun 2023 15:21:05 +0300 Subject: [PATCH 03/11] FIX: removed duplicated async to sync implementation --- CHANGELOG.md | 2 +- Cargo.lock | 12 +-- api/derive/Cargo.toml | 2 +- api/info/Cargo.toml | 2 +- ton_client/Cargo.toml | 2 +- ton_client/src/abi/tests.rs | 4 +- ton_client/src/boc/tests.rs | 19 +++-- ton_client/src/json_interface/runtime.rs | 73 +------------------ .../src/processing/wait_for_transaction.rs | 6 +- ton_client_processing/Cargo.toml | 2 +- ton_sdk/Cargo.toml | 2 +- toncli/Cargo.toml | 2 +- tools/package.json | 2 +- 13 files changed, 30 insertions(+), 100 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b28aaee9f..baaa21f1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. -## [1.43.3] – 2023-06-24 +## [1.44.0] – 2023-06-24 ### New diff --git a/Cargo.lock b/Cargo.lock index 34ec7ab93..cef556452 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -113,7 +113,7 @@ checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8" [[package]] name = "api_derive" -version = "1.43.3" +version = "1.44.0" dependencies = [ "api_info", "proc-macro2", @@ -124,7 +124,7 @@ dependencies = [ [[package]] name = "api_info" -version = "1.43.3" +version = "1.44.0" dependencies = [ "serde", "serde_derive", @@ -2601,7 +2601,7 @@ dependencies = [ [[package]] name = "ton_client" -version = "1.43.3" +version = "1.44.0" dependencies = [ "aes", "api_derive", @@ -2668,7 +2668,7 @@ dependencies = [ [[package]] name = "ton_client_processing" -version = "1.43.3" +version = "1.44.0" dependencies = [ "api_derive", "api_info", @@ -2700,7 +2700,7 @@ dependencies = [ [[package]] name = "ton_sdk" -version = "1.43.3" +version = "1.44.0" dependencies = [ "api_derive", "api_info", @@ -2807,7 +2807,7 @@ dependencies = [ [[package]] name = "toncli" -version = "1.43.3" +version = "1.44.0" dependencies = [ "api_info", "assert_cmd", diff --git a/api/derive/Cargo.toml b/api/derive/Cargo.toml index 3fdd0b80b..88bac0eae 100644 --- a/api/derive/Cargo.toml +++ b/api/derive/Cargo.toml @@ -2,7 +2,7 @@ authors = [ 'TON Labs LTD ' ] edition = '2018' name = 'api_derive' -version = '1.43.3' +version = '1.44.0' [dependencies] quote = '1.0.26' diff --git a/api/info/Cargo.toml b/api/info/Cargo.toml index bf246596f..c0caeae84 100644 --- a/api/info/Cargo.toml +++ b/api/info/Cargo.toml @@ -2,7 +2,7 @@ authors = [ 'TON Labs LTD ' ] edition = '2018' name = 'api_info' -version = '1.43.3' +version = '1.44.0' [dependencies] serde = '1.0.115' diff --git a/ton_client/Cargo.toml b/ton_client/Cargo.toml index 9341defdd..4cd46ba36 100644 --- a/ton_client/Cargo.toml +++ b/ton_client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'ton_client' -version = '1.43.3' +version = '1.44.0' authors = [ 'TON Labs LTD ' ] edition = '2018' license = 'Apache-2.0' diff --git a/ton_client/src/abi/tests.rs b/ton_client/src/abi/tests.rs index 0e47a53ed..1f7d6161c 100644 --- a/ton_client/src/abi/tests.rs +++ b/ton_client/src/abi/tests.rs @@ -466,8 +466,8 @@ fn test_is_empty_pubkey() -> Result<()> { Ok(()) } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_resolve_pubkey() -> Result<()> { +#[test] +fn test_resolve_pubkey() -> Result<()> { let context = crate::ClientContext::new(crate::ClientConfig::default()).unwrap(); let tvc = base64::encode(include_bytes!("../tests/contracts/abi_v2/Hello.tvc")); let mut deploy_set = DeploySet { diff --git a/ton_client/src/boc/tests.rs b/ton_client/src/boc/tests.rs index 7925a862a..b86796652 100644 --- a/ton_client/src/boc/tests.rs +++ b/ton_client/src/boc/tests.rs @@ -27,8 +27,8 @@ use std::str::FromStr; use ton_block::{MsgAddrStd, MsgAddressInt, Serializable}; use ton_types::{AccountId, BuilderData, IBitstring}; -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_encode_boc() { +#[test] +fn test_encode_boc() { fn write_b(value: u8) -> BuilderOp { BuilderOp::Integer { size: 1, @@ -182,8 +182,8 @@ async fn test_encode_boc() { assert_eq!(boc, response.boc); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_pinned_cache() { +#[test] +fn test_pinned_cache() { let client = TestClient::new(); let cache_set = client.wrap(cache_set, BocModule::api(), super::cache::cache_set_api()); let cache_get = client.wrap(cache_get, BocModule::api(), super::cache::cache_get_api()); @@ -324,8 +324,8 @@ async fn test_pinned_cache() { assert_eq!(boc.boc, None); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_unpinned_cache() { +#[test] +fn test_unpinned_cache() { let boc1 = TestClient::tvc(crate::tests::TEST_DEBOT, None).unwrap(); let boc2 = TestClient::tvc(crate::tests::SUBSCRIBE, None).unwrap(); @@ -899,8 +899,8 @@ fn encode_external_in_message() { assert_eq!(boc_encoded.message, abi_encoded.message); } -#[tokio::test(flavor = "multi_thread", worker_threads = 2)] -async fn test_decode_tvc() { +#[test] +fn test_decode_tvc() { let client = TestClient::new(); let tvc_boc = "te6ccgEBBQEAMgACCQFn9wzgAwEBAtACACZTb21lIFNtYXJ0IENvbnRyYWN0ART/APSkE/S88sgLBAAC0w=="; let code_boc = "te6ccgEBAgEAEAABFP8A9KQT9LzyyAsBAALT"; @@ -933,13 +933,12 @@ async fn test_decode_tvc() { }); let decoded = client - .request_async::( + .request::( "boc.decode_tvc", json!({ "tvc": tvc_boc, }), ) - .await .unwrap(); assert_eq!(expected, decoded); } diff --git a/ton_client/src/json_interface/runtime.rs b/ton_client/src/json_interface/runtime.rs index f815b42fc..45802b6cc 100644 --- a/ton_client/src/json_interface/runtime.rs +++ b/ton_client/src/json_interface/runtime.rs @@ -15,11 +15,10 @@ use super::modules::register_modules; use super::request::Request; use crate::client::{ClientConfig, ClientContext, Error}; -use crate::error::{ClientError, ClientResult}; -use crate::{ContextHandle, ResponseType}; +use crate::error::ClientResult; +use crate::ContextHandle; use api_info::{Module, API}; use std::collections::HashMap; -use std::sync::mpsc::Sender; use std::sync::{Arc, Mutex, MutexGuard}; pub(crate) trait SyncHandler { @@ -89,72 +88,6 @@ lazy_static! { pub struct Runtime; -// Used as a `request_ptr` in case when async handler invoker via `dispatch_sync` -struct AsyncAsSyncHandler { - // Used to send async result to the waiting sync handler. - result_sender: Sender>, - // Indicates that async result (success or error) is already sent to the sync handler - // and async handler should ignore all following responses. - result_sent: bool, -} - -impl AsyncAsSyncHandler { - fn dispatch( - context: Arc, - function_name: String, - params_json: String, - ) -> ClientResult { - let (result_sender, result_receiver) = std::sync::mpsc::channel::>(); - // Create state, unbox it into raw pointer and send to the `dispatch_sync` - let handler = Box::into_raw(Box::new(Self { - result_sender, - result_sent: false, - })); - Runtime::dispatch_async( - context, - function_name, - params_json, - Request::new_with_ptr(handler as *const (), Self::response_handler), - ); - let result = result_receiver - .recv() - .unwrap_or_else(|err| Err(Error::can_not_receive_request_result(err))); - result - } - - fn handle_response(&mut self, params_json: String, response_type: u32) { - if self.result_sent { - return; - } - let result = if response_type == ResponseType::Success as u32 { - Ok(params_json) - } else if response_type == ResponseType::Error as u32 { - Err(serde_json::from_str::(¶ms_json) - .unwrap_or_else(|err| Error::callback_params_cant_be_converted_to_json(err))) - } else { - return; - }; - let _ = self.result_sender.send(result); - self.result_sent = true; - } - - fn response_handler( - request_ptr: *const (), - params_json: String, - response_type: u32, - finished: bool, - ) { - let handler = request_ptr as *mut Self; - if let Some(handler) = unsafe { handler.as_mut() } { - handler.handle_response(params_json, response_type); - } - if finished { - // Box handler from raw pointer and drop it - let _ = unsafe { Box::from_raw(handler) }; - } - } -} - impl Runtime { fn handlers() -> &'static RuntimeHandlers { &HANDLERS @@ -171,7 +104,7 @@ impl Runtime { ) -> ClientResult { match Self::handlers().sync_handlers.get(&function_name) { Some(handler) => handler.handle(context, params_json.as_str()), - None => AsyncAsSyncHandler::dispatch(context, function_name, params_json), + None => Err(Error::unknown_function(&function_name)), } } diff --git a/ton_client/src/processing/wait_for_transaction.rs b/ton_client/src/processing/wait_for_transaction.rs index 988e76693..613dec627 100644 --- a/ton_client/src/processing/wait_for_transaction.rs +++ b/ton_client/src/processing/wait_for_transaction.rs @@ -322,10 +322,8 @@ async fn wait_by_block_walking + Send>( // Block walking loop loop { let now = context.env.now_ms(); - let fetch_block_timeout = (std::cmp::max(max_block_time, now) - now - + processing_timeout as u64) - .try_into() - .unwrap_or(u32::MAX); + let timeout = std::cmp::max(max_block_time, now) - now + processing_timeout as u64; + let fetch_block_timeout = timeout.try_into().unwrap_or(u32::MAX); log::debug!("fetch_block_timeout {}", fetch_block_timeout); let block = fetching::fetch_next_shard_block( diff --git a/ton_client_processing/Cargo.toml b/ton_client_processing/Cargo.toml index 312804b31..b75e0a96b 100644 --- a/ton_client_processing/Cargo.toml +++ b/ton_client_processing/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'ton_client_processing' -version = '1.43.3' +version = '1.44.0' authors = [ 'TON Labs LTD ' ] edition = '2018' license = 'Apache-2.0' diff --git a/ton_sdk/Cargo.toml b/ton_sdk/Cargo.toml index f86f8519f..4c40e8a75 100644 --- a/ton_sdk/Cargo.toml +++ b/ton_sdk/Cargo.toml @@ -1,6 +1,6 @@ [package] name = 'ton_sdk' -version = '1.43.3' +version = '1.44.0' edition = '2018' license = 'Apache-2.0' authors = [ 'TON Labs LTD ' ] diff --git a/toncli/Cargo.toml b/toncli/Cargo.toml index 5cf2c2051..d18f275b6 100644 --- a/toncli/Cargo.toml +++ b/toncli/Cargo.toml @@ -9,7 +9,7 @@ license = 'Apache-2.0' name = 'toncli' readme = 'README.md' repository = 'https://github.com/tonlabs/ever-sdk' -version = '1.43.3' +version = '1.44.0' [dependencies] base64 = '0.13.0' diff --git a/tools/package.json b/tools/package.json index de7b1e1fd..6436882dc 100644 --- a/tools/package.json +++ b/tools/package.json @@ -1,6 +1,6 @@ { "name": "tools", - "version": "1.43.3", + "version": "1.44.0", "description": "", "main": "index.js", "scripts": { From 2ff5d28250561cbf19aadcef41440578e64dba4b Mon Sep 17 00:00:00 2001 From: Michael Vlasov Date: Fri, 30 Jun 2023 16:52:28 +0300 Subject: [PATCH 04/11] FIX: removed duplicated async to sync implementation --- ton_client/src/client/tests.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/ton_client/src/client/tests.rs b/ton_client/src/client/tests.rs index e5c10136a..80cbf6bf6 100644 --- a/ton_client/src/client/tests.rs +++ b/ton_client/src/client/tests.rs @@ -82,11 +82,6 @@ fn test_invalid_params_error_secret_stripped() { assert!(!error.message.contains(secret)); } -#[test] -fn test_sync_calls() { - -} - #[tokio::test] async fn test_memory_leak() { for _ in 0..1 { From 4adf98b393dc6d2b3d80a3932f88e335e809522e Mon Sep 17 00:00:00 2001 From: tonjen Date: Wed, 12 Jul 2023 13:00:51 +0000 Subject: [PATCH 05/11] Update package version --- api/test/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/test/Cargo.toml b/api/test/Cargo.toml index 4e08034c6..f0f9f0862 100644 --- a/api/test/Cargo.toml +++ b/api/test/Cargo.toml @@ -2,7 +2,7 @@ authors = [ 'TON Labs LTD ' ] edition = '2018' name = 'api_test' -version = '1.43.3' +version = '1.44.0' [dependencies] serde = '1.0.115' From d3e5c85bb4e32ffd288a4728c5c84e6947a8bdb8 Mon Sep 17 00:00:00 2001 From: tonjen Date: Wed, 12 Jul 2023 13:04:29 +0000 Subject: [PATCH 06/11] Update docs --- Cargo.lock | 2 +- tools/api.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index cef556452..026cc4722 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -133,7 +133,7 @@ dependencies = [ [[package]] name = "api_test" -version = "1.43.3" +version = "1.44.0" dependencies = [ "api_derive", "api_info", diff --git a/tools/api.json b/tools/api.json index 8065e832c..5506a9ba9 100644 --- a/tools/api.json +++ b/tools/api.json @@ -1,5 +1,5 @@ { - "version": "1.43.3", + "version": "1.44.0", "modules": [ { "name": "client", From 7769c0ec38f34f14fa7fd82ae01b4151f6c8f1bd Mon Sep 17 00:00:00 2001 From: tonjen Date: Wed, 12 Jul 2023 13:08:18 +0000 Subject: [PATCH 07/11] Update trusted blocks --- ton_client/src/proofs/trusted_key_blocks.bin | Bin 425320 -> 437488 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/ton_client/src/proofs/trusted_key_blocks.bin b/ton_client/src/proofs/trusted_key_blocks.bin index 6b5b47611f37eb3aab63a96717548c5c4ca3cb7a..df67b1966c57a694c020e3d0cc6525983545fb97 100644 GIT binary patch delta 12312 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 From a1604ad9274e8b3b1b6ce839819fa73a8eadf4fe Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Wed, 12 Jul 2023 17:33:09 +0300 Subject: [PATCH 08/11] Fix monitor tests --- ton_client_processing/src/tests.rs | 28 +++++++--------------------- 1 file changed, 7 insertions(+), 21 deletions(-) diff --git a/ton_client_processing/src/tests.rs b/ton_client_processing/src/tests.rs index bdfbd8ee7..1174a7ef5 100644 --- a/ton_client_processing/src/tests.rs +++ b/ton_client_processing/src/tests.rs @@ -15,9 +15,7 @@ use ton_types::{AccountId, UInt256}; async fn test_fetch() { let api = sdk_services(); let mon = MessageMonitor::new(api.clone()); - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); let info = mon.get_queue_info("1").unwrap(); assert_eq!(info.resolved, 0); assert_eq!(info.unresolved, 2); @@ -47,9 +45,7 @@ async fn test_fetch() { async fn test_cancel_monitor() { let api = sdk_services(); let mon = MessageMonitor::new(api.clone()); - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); let info = mon.get_queue_info("1").unwrap(); assert_eq!(info.resolved, 0); assert_eq!(info.unresolved, 2); @@ -63,9 +59,7 @@ async fn test_cancel_monitor() { async fn test_fetch_at_least_one() { let api = sdk_services(); let mon = MessageMonitor::new(api.clone()); - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); let results = mon .fetch_next_monitor_results("1", MonitorFetchWaitMode::NoWait) .await @@ -99,9 +93,7 @@ async fn test_fetch_wait_all() { let mon = Arc::new(MessageMonitor::new(api.clone())); // Start monitoring for [1, 2] messages - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); sleep(Duration::from_millis(1100)).await; @@ -158,9 +150,7 @@ async fn test_mon_info() { let info = mon.get_queue_info("1").unwrap(); assert_eq!(info.resolved, 0); assert_eq!(info.unresolved, 0); - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); sleep(Duration::from_millis(1100)).await; let info = mon.get_queue_info("1").unwrap(); assert_eq!(info.resolved, 0); @@ -177,9 +167,7 @@ async fn test_buffering() { let api = sdk_services(); let mon = MessageMonitor::new(api.clone()); - mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(1, 1), msg(2, 2)]).unwrap(); tokio::time::sleep(Duration::from_millis(100)).await; assert_eq!( api.active_subscription_count(), @@ -194,9 +182,7 @@ async fn test_buffering() { "first subscription should be started after 1 second" ); - mon.monitor_messages("1", vec![msg(3, 3), msg(4, 4)]) - .await - .unwrap(); + mon.monitor_messages("1", vec![msg(3, 3), msg(4, 4)]).unwrap(); tokio::time::sleep(Duration::from_millis(100)).await; assert_eq!( api.active_subscription_count(), From 99b006cf233f688eeafda7d3647c9ee0a10b1b7b Mon Sep 17 00:00:00 2001 From: Sergei Voronezhskii Date: Wed, 12 Jul 2023 18:25:37 +0300 Subject: [PATCH 09/11] Version 1.44.0 --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index baaa21f1e..314dff82e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file. -## [1.44.0] – 2023-06-24 +## [1.44.0] – 2023-07-12 ### New From 949cf6a772adad72a86a7298c31fe025c629a063 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Thu, 13 Jul 2023 13:33:54 +0300 Subject: [PATCH 10/11] CachedBoc --- ton_client/src/boc/cache.rs | 41 ++++++++++++++++++++++++++++++++++--- ton_client/src/boc/mod.rs | 4 ++-- 2 files changed, 40 insertions(+), 5 deletions(-) diff --git a/ton_client/src/boc/cache.rs b/ton_client/src/boc/cache.rs index 07b1572dd..7ef7dee99 100644 --- a/ton_client/src/boc/cache.rs +++ b/ton_client/src/boc/cache.rs @@ -101,13 +101,13 @@ pub struct PinnedBoc { cell: Cell, } -pub struct CachedBoc { +pub struct InnerCachedBoc { size: usize, cell: Cell, } pub struct CachedBocs { - bocs: LruCache, + bocs: LruCache, cache_size: usize, } @@ -200,7 +200,7 @@ impl Bocs { .ok_or(Error::insufficient_cache_size(self.max_cache_size, size))?; lock.cache_size -= entry.size; } - lock.bocs.put(hash.clone(), CachedBoc { cell, size }); + lock.bocs.put(hash.clone(), InnerCachedBoc { cell, size }); lock.cache_size += size; Ok(()) @@ -391,3 +391,38 @@ pub fn cache_unpin( context.bocs.unpin(¶ms.pin, hash); Ok(()) } + +pub struct CachedBoc { + context: Arc, + boc_ref: String, + pin: String, +} + +impl CachedBoc { + pub fn new(context: Arc, boc: String, pin: String) -> ClientResult { + let boc_ref = cache_set( + context.clone(), + ParamsOfBocCacheSet { + boc, + cache_type: BocCacheType::Pinned { pin: pin.clone() }, + })?.boc_ref; + + Ok(Self { context, boc_ref, pin }) + } + + pub fn boc_ref(&self) -> String { + self.boc_ref.clone() + } +} + +impl Drop for CachedBoc { + fn drop(&mut self) { + let _ = cache_unpin( + self.context.clone(), + ParamsOfBocCacheUnpin { + pin: std::mem::take(&mut self.pin), + boc_ref: Some(std::mem::take(&mut self.boc_ref)) + } + ); + } +} diff --git a/ton_client/src/boc/mod.rs b/ton_client/src/boc/mod.rs index 97fa664ac..6683bee8a 100644 --- a/ton_client/src/boc/mod.rs +++ b/ton_client/src/boc/mod.rs @@ -31,8 +31,8 @@ pub use blockchain_config::{ get_blockchain_config, ParamsOfGetBlockchainConfig, ResultOfGetBlockchainConfig, }; pub use cache::{ - cache_get, cache_set, cache_unpin, BocCacheType, ParamsOfBocCacheGet, ParamsOfBocCacheSet, - ParamsOfBocCacheUnpin, ResultOfBocCacheGet, ResultOfBocCacheSet, + cache_get, cache_set, cache_unpin, BocCacheType, CachedBoc, ParamsOfBocCacheGet, + ParamsOfBocCacheSet, ParamsOfBocCacheUnpin, ResultOfBocCacheGet, ResultOfBocCacheSet, }; pub use common::{ get_boc_depth, get_boc_hash, ParamsOfGetBocDepth, ParamsOfGetBocHash, ResultOfGetBocDepth, From 7478254778c2e4e89a13e1e4c609f942211dde56 Mon Sep 17 00:00:00 2001 From: Alexey Vavilin Date: Thu, 13 Jul 2023 17:26:43 +0300 Subject: [PATCH 11/11] try_clone and Debug for CachedBoc --- ton_client/src/boc/cache.rs | 5 +++++ ton_client/src/client/client.rs | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/ton_client/src/boc/cache.rs b/ton_client/src/boc/cache.rs index 7ef7dee99..950cbbe2c 100644 --- a/ton_client/src/boc/cache.rs +++ b/ton_client/src/boc/cache.rs @@ -392,6 +392,7 @@ pub fn cache_unpin( Ok(()) } +#[derive(Debug)] pub struct CachedBoc { context: Arc, boc_ref: String, @@ -413,6 +414,10 @@ impl CachedBoc { pub fn boc_ref(&self) -> String { self.boc_ref.clone() } + + pub fn try_clone(&self) -> ClientResult { + CachedBoc::new(self.context.clone(), self.boc_ref.clone(), self.pin.clone()) + } } impl Drop for CachedBoc { diff --git a/ton_client/src/client/client.rs b/ton_client/src/client/client.rs index 80cd706f9..529b821ae 100644 --- a/ton_client/src/client/client.rs +++ b/ton_client/src/client/client.rs @@ -83,6 +83,12 @@ pub struct ClientContext { pub(crate) debots: LockfreeMap>, } +impl std::fmt::Debug for ClientContext { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ClientContext").finish() + } +} + impl ClientContext { pub(crate) fn get_server_link(&self) -> ClientResult<&ServerLink> { self.net.get_server_link()