From 437e08172b7fe7b9cc6d6bd2dbfd3e10674c70e4 Mon Sep 17 00:00:00 2001 From: Ivan Suvorov Date: Fri, 30 Sep 2022 16:38:17 +0300 Subject: [PATCH 01/12] Refactoring subscriptions --- src/account.rs | 46 ++++++++++++++++++++-------------------------- 1 file changed, 20 insertions(+), 26 deletions(-) diff --git a/src/account.rs b/src/account.rs index 84b7673c..018a1c82 100644 --- a/src/account.rs +++ b/src/account.rs @@ -10,6 +10,7 @@ * See the License for the specific TON DEV software governing permissions and * limitations under the License. */ +use std::sync::Arc; use crate::helpers::{check_dir, create_client_verbose, json_account, print_account, query_account_field}; use crate::config::Config; use serde_json::{json, Value}; @@ -302,17 +303,6 @@ pub async fn dump_accounts(config: &Config, addresses: Vec, path: Option Ok(()) } -lazy_static::lazy_static! { - static ref TX: tokio::sync::Mutex>>> = - tokio::sync::Mutex::new(None); -} - -async fn terminate(res: Result<(), String>) { - let lock = TX.lock().await; - let tx = lock.as_ref().unwrap().clone(); - tx.send(res).await.unwrap(); -} - fn extract_last_trans_lt(v: &serde_json::Value) -> Option<&str> { v.as_object()?["last_trans_lt"].as_str() } @@ -340,22 +330,26 @@ pub async fn wait_for_change(config: &Config, account_address: &str, wait_secs: .ok_or_else(|| format!("Failed to parse query result: {}", query.result[0]))?; let (s, mut r) = tokio::sync::mpsc::channel(1); - *TX.lock().await = Some(s); + let s = Arc::new(s); - let callback = |result: Result| async { - let res = match result { - Ok(res) => { - if extract_last_trans_lt(&res.result).is_some() { - Ok(()) - } else { - Err(format!("Can't parse the result: {}", res.result)) + let ss = s.clone(); + let callback = move |result: Result| { + let s = ss.clone(); + async move { + let res = match result { + Ok(res) => { + if extract_last_trans_lt(&res.result).is_some() { + Ok(()) + } else { + Err(format!("Can't parse the result: {}", res.result)) + } } - } - Err(e) => { - Err(format!("Client error: {}", e)) - } - }; - terminate(res).await + Err(e) => { + Err(format!("Client error: {}", e)) + } + }; + s.send(res).await.unwrap() + } }; let subscription = ton_client::net::subscribe_collection( @@ -378,7 +372,7 @@ pub async fn wait_for_change(config: &Config, account_address: &str, wait_secs: tokio::spawn(async move { tokio::time::sleep(std::time::Duration::from_secs(wait_secs)).await; - terminate(Err("Timeout".to_owned())).await + s.send(Err("Timeout".to_owned())).await.unwrap() }); let res = r.recv().await.ok_or_else(|| "Sender has dropped".to_owned())?; From 85f3517bcffd79b1d38c1931bdd81e03b5e4dd56 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Mon, 3 Oct 2022 19:46:46 +0400 Subject: [PATCH 02/12] Fixed alternative syntax and added test --- src/call.rs | 2 +- tests/samples/test.abi.json | 42 ++ tests/samples/test.code | 272 +++++++++++ tests/samples/test.debug.json | 836 ++++++++++++++++++++++++++++++++++ tests/samples/test.sol | 18 + tests/samples/test.tvc | Bin 0 -> 475 bytes tests/test_cli.rs | 42 +- 7 files changed, 1210 insertions(+), 2 deletions(-) create mode 100644 tests/samples/test.abi.json create mode 100644 tests/samples/test.code create mode 100644 tests/samples/test.debug.json create mode 100644 tests/samples/test.sol create mode 100644 tests/samples/test.tvc diff --git a/src/call.rs b/src/call.rs index dcacb3ea..d62567e1 100644 --- a/src/call.rs +++ b/src/call.rs @@ -78,7 +78,7 @@ async fn build_json_from_params(params_vec: Vec<&str>, abi_path: &str, method: & let mut params_json = json!({ }); for input in inputs { let mut iter = params_vec.iter(); - let _param = iter.find(|x| x.trim_start_matches('-') == input.name) + let _param = iter.find(|x| x.starts_with('-') && (x.trim_start_matches('-') == input.name)) .ok_or(format!(r#"argument "{}" of type "{}" not found"#, input.name, input.kind))?; let value = iter.next() diff --git a/tests/samples/test.abi.json b/tests/samples/test.abi.json new file mode 100644 index 00000000..bc646295 --- /dev/null +++ b/tests/samples/test.abi.json @@ -0,0 +1,42 @@ +{ + "ABI version": 2, + "version": "2.3", + "header": ["time", "expire"], + "functions": [ + { + "name": "test", + "inputs": [ + {"name":"ctype","type":"uint256"}, + {"name":"data","type":"string"} + ], + "outputs": [ + ] + }, + { + "name": "get", + "inputs": [ + {"name":"ctype","type":"uint256"}, + {"name":"data","type":"string"} + ], + "outputs": [ + {"name":"value0","type":"uint256"} + ] + }, + { + "name": "constructor", + "inputs": [ + ], + "outputs": [ + ] + } + ], + "data": [ + ], + "events": [ + ], + "fields": [ + {"name":"_pubkey","type":"uint256"}, + {"name":"_timestamp","type":"uint64"}, + {"name":"_constructorFlag","type":"bool"} + ] +} diff --git a/tests/samples/test.code b/tests/samples/test.code new file mode 100644 index 00000000..ec6e0b4a --- /dev/null +++ b/tests/samples/test.code @@ -0,0 +1,272 @@ +.version sol 0.65.0 + +.macro constructor +DROP +GETGLOB 2 +ISNULL +IFREF { + CALL $c4_to_c7_with_init_storage$ +} +GETGLOB 6 +THROWIF 51 +ENDS +ACCEPT +CALLREF { + CALL $c7_to_c4$ +} +THROW 0 + +.macro test +DROP +GETGLOB 6 +THROWIFNOT 76 +GETGLOB 2 +ISNULL +IFREF { + CALL $c4_to_c7$ +} +.loc test.sol, 12 +LDU 256 +LDREF +ENDS +.loc test.sol, 0 +CALLREF { + CALL $test_ad1c61fd_internal_macro$ +} +CALLREF { + CALL $c7_to_c4$ +} +THROW 0 + +.globl test_ad1c61fd_internal +.type test_ad1c61fd_internal, @function +CALL $test_ad1c61fd_internal_macro$ + +.macro test_ad1c61fd_internal_macro +.loc test.sol, 7 +DROP2 +GETGLOB 5 +DUP +ISNULL +PUSHCONT { + DROP + PUSHINT 0 +} +IF +GETGLOB 2 +EQUAL +THROWIFNOT 102 +.loc test.sol, 8 +ACCEPT +.loc test.sol, 0 + +.macro get +DROP +GETGLOB 6 +THROWIFNOT 76 +GETGLOB 2 +ISNULL +IFREF { + CALL $c4_to_c7$ +} +.loc test.sol, 15 +LDU 256 +LDREF +ENDS +.loc test.sol, 0 +CALLREF { + CALL $get_805da4ad_internal_macro$ +} +OVER +PUSHCONT { + PUSH S3 + CTOS + LDU 2 + LDMSGADDR + DROP + NIP + NEWC + STSLICECONST xc + STSLICE + PUSHINT 2363537267 + STUR 130 + STU 256 + ENDC + PUSHINT 0 + SENDRAWMSG +} +PUSHCONT { + DROP +} +IFELSE +CALLREF { + CALL $c7_to_c4$ +} +THROW 0 + +.globl get_805da4ad_internal +.type get_805da4ad_internal, @function +CALL $get_805da4ad_internal_macro$ + +.macro get_805da4ad_internal_macro +.loc test.sol, 16 +DROP +INC +.loc test.sol, 0 + +.macro c4_to_c7 +PUSHROOT +CTOS +LDU 256 ; pubkey c4 +LDU 64 ; pubkey timestamp c4 +LDU 1 ; ctor flag +NIP +ENDS +SETGLOB 3 +SETGLOB 2 + +.macro c4_to_c7_with_init_storage +PUSHROOT +CTOS +SBITS +GTINT 1 +PUSHCONT { + PUSHINT 0 + PUSHROOT + CTOS + PLDDICT ; D + PUSHINT 64 + DICTUGET + THROWIFNOT 61 + PLDU 256 + SETGLOB 2 + PUSHINT 0 ; timestamp + SETGLOB 3 +} +IFREFELSE { + CALL $c4_to_c7$ +} + +.macro c7_to_c4 +GETGLOB 3 +GETGLOB 2 +NEWC +STU 256 +STU 64 +STONE +ENDC +POPROOT + +.macro upd_only_time_in_c4 +PUSHROOT +CTOS +LDU 256 +LDU 64 +NIP +GETGLOB 3 +ROT +NEWC +STU 256 +STU 64 +STSLICE +ENDC +POPROOT + +.internal-alias :main_internal, 0 +.internal :main_internal +PUSHROOT +CTOS +SBITS +NEQINT 1 +SETGLOB 6 +PUSH S2 +CTOS +PLDU 4 +MODPOW2 1 +IFRET +OVER +SEMPTY ; isEmpty +IFJMPREF { + GETGLOB 6 + THROWIFNOT 76 +} +OVER +LDUQ 32 ; [funcId] body' ok +THROWIFNOT 60 +OVER +IFNOTJMPREF { + GETGLOB 6 + THROWIFNOT 76 +} +SWAP +CALLREF { + CALL $public_function_selector$ +} +THROW 60 + +.internal-alias :main_external, -1 +.internal :main_external +PUSHROOT +CTOS +SBITS +NEQINT 1 +SETGLOB 6 +OVER +CALLREF { + CALL $c4_to_c7_with_init_storage$ +} +LDU 1 ; haveSign msgSlice +SWAP +PUSHCONT { + PUSHPOW2 9 + LDSLICEX + DUP + MYADDR + NEWC + STSLICE + STSLICE + ENDC + HASHCU + ROT + GETGLOB 2 + DUP + SETGLOB 5 + CHKSIGNU + THROWIFNOT 40 +} +IF +LDU 64 ; timestamp msgSlice +SWAP +CALL $replay_protection_macro$ +LDU 32 ; expireAt msgSlice +SWAP +NOW ; msgSlice expireAt now +GREATER ; msgSlice expireAt>now +THROWIFNOT 57 +LDU 32 ; funcId body +SWAP +CALLREF { + CALL $public_function_selector$ +} +THROW 60 + +.macro public_function_selector +DUP +PUSHINT 216053619 +EQUAL +IFJMPREF { + CALL $get$ +} +DUP +PUSHINT 1756716863 +EQUAL +IFJMPREF { + CALL $constructor$ +} +DUP +PUSHINT 1967234084 +EQUAL +IFJMPREF { + CALL $test$ +} + diff --git a/tests/samples/test.debug.json b/tests/samples/test.debug.json new file mode 100644 index 00000000..afa4856e --- /dev/null +++ b/tests/samples/test.debug.json @@ -0,0 +1,836 @@ +{ + "map": { + "222d1d521fc463dfa85826e00514a3dcbb4f6a064f5c4a012d377b298c912aa4": { + "0": { + "filename": "./test.code", + "line": 64 + }, + "8": { + "filename": "./test.code", + "line": 65 + }, + "24": { + "filename": "./test.code", + "line": 66 + }, + "48": { + "filename": "./test.code", + "line": 67 + }, + "64": { + "filename": "./test.code", + "line": 68 + }, + "72": { + "filename": "./test.code", + "line": 69 + }, + "88": { + "filename": "test.sol", + "line": 15 + }, + "104": { + "filename": "test.sol", + "line": 15 + }, + "112": { + "filename": "test.sol", + "line": 15 + }, + "120": { + "filename": "./test.code", + "line": 77 + }, + "136": { + "filename": "./test.code", + "line": 80 + }, + "144": { + "filename": "./test.code", + "line": 81 + }, + "160": { + "filename": "./test.code", + "line": 82 + }, + "168": { + "filename": "./test.code", + "line": 83 + }, + "176": { + "filename": "./test.code", + "line": 84 + }, + "192": { + "filename": "./test.code", + "line": 85 + }, + "208": { + "filename": "./test.code", + "line": 86 + }, + "216": { + "filename": "./test.code", + "line": 87 + }, + "224": { + "filename": "./test.code", + "line": 88 + }, + "232": { + "filename": "./test.code", + "line": 89 + }, + "256": { + "filename": "./test.code", + "line": 90 + }, + "264": { + "filename": "./test.code", + "line": 91 + }, + "312": { + "filename": "./test.code", + "line": 92 + }, + "336": { + "filename": "./test.code", + "line": 93 + }, + "352": { + "filename": "./test.code", + "line": 94 + }, + "360": { + "filename": "./test.code", + "line": 95 + }, + "368": { + "filename": "./test.code", + "line": 96 + }, + "384": { + "filename": "./test.code", + "line": 98 + }, + "392": { + "filename": "./test.code", + "line": 99 + }, + "400": { + "filename": "./test.code", + "line": 101 + }, + "408": { + "filename": "./test.code", + "line": 102 + }, + "424": { + "filename": "./test.code", + "line": 105 + } + }, + "42aa676d16d19f95a85a3a8f6b8578c96167a12005f5a454dcdc62d5181d3cf4": { + "0": { + "filename": "./test.code", + "line": 4 + }, + "8": { + "filename": "./test.code", + "line": 5 + }, + "24": { + "filename": "./test.code", + "line": 6 + }, + "32": { + "filename": "./test.code", + "line": 7 + }, + "48": { + "filename": "./test.code", + "line": 10 + }, + "64": { + "filename": "./test.code", + "line": 11 + }, + "80": { + "filename": "./test.code", + "line": 12 + }, + "88": { + "filename": "./test.code", + "line": 13 + }, + "104": { + "filename": "./test.code", + "line": 14 + }, + "120": { + "filename": "./test.code", + "line": 17 + } + }, + "5f92e5ad08e197a2a83dfe52ccfd8cda4e774a7c2293b2dc41720b524280ba6c": { + "0": { + "filename": "test.sol", + "line": 16 + }, + "8": { + "filename": "test.sol", + "line": 16 + } + }, + "60488e96384d55db5809d3be340ce676908c99e02e0f6a89a307f1376c1ceb17": { + "0": { + "filename": "./test.code", + "line": 151 + }, + "16": { + "filename": "./test.code", + "line": 152 + }, + "32": { + "filename": "./test.code", + "line": 153 + }, + "40": { + "filename": "./test.code", + "line": 154 + }, + "56": { + "filename": "./test.code", + "line": 155 + }, + "72": { + "filename": "./test.code", + "line": 156 + }, + "88": { + "filename": "./test.code", + "line": 157 + }, + "96": { + "filename": "./test.code", + "line": 158 + } + }, + "6756ea8d3936b355037eecf00dc91523d250b86b3482191f9eb82a15054e8dde": { + "0": { + "filename": "", + "line": 1 + }, + "24": { + "filename": "", + "line": 2 + }, + "40": { + "filename": "", + "line": 3 + } + }, + "ab3affad94ee30ab74c564a738e4f69e51ba89449fbcef0729e0114e76d9571a": { + "0": { + "filename": "./test.code", + "line": 20 + }, + "8": { + "filename": "./test.code", + "line": 21 + }, + "24": { + "filename": "./test.code", + "line": 22 + }, + "48": { + "filename": "./test.code", + "line": 23 + }, + "64": { + "filename": "./test.code", + "line": 24 + }, + "72": { + "filename": "./test.code", + "line": 25 + }, + "88": { + "filename": "test.sol", + "line": 12 + }, + "104": { + "filename": "test.sol", + "line": 12 + }, + "112": { + "filename": "test.sol", + "line": 12 + }, + "120": { + "filename": "./test.code", + "line": 33 + }, + "136": { + "filename": "./test.code", + "line": 36 + }, + "152": { + "filename": "./test.code", + "line": 39 + } + }, + "b6f27d187f26bd046272f9f471e9ae01f051b960e654874ac3fb0749c691c4c6": { + "0": { + "filename": "./test.code", + "line": 129 + }, + "16": { + "filename": "./test.code", + "line": 130 + }, + "24": { + "filename": "./test.code", + "line": 131 + }, + "40": { + "filename": "./test.code", + "line": 132 + }, + "56": { + "filename": "./test.code", + "line": 133 + }, + "72": { + "filename": "./test.code", + "line": 134 + }, + "80": { + "filename": "./test.code", + "line": 135 + }, + "96": { + "filename": "./test.code", + "line": 136 + }, + "104": { + "filename": "./test.code", + "line": 137 + }, + "120": { + "filename": "./test.code", + "line": 138 + }, + "136": { + "filename": "./test.code", + "line": 139 + }, + "152": { + "filename": "./test.code", + "line": 140 + }, + "168": { + "filename": "./test.code", + "line": 141 + }, + "192": { + "filename": "./test.code", + "line": 142 + }, + "208": { + "filename": "./test.code", + "line": 143 + }, + "216": { + "filename": "./test.code", + "line": 144 + }, + "232": { + "filename": "./test.code", + "line": 146 + } + }, + "bd4b1cf14908b5a0501126889719205d7662cf375a0f5de52b9e6838bb3070e2": { + "0": { + "filename": "./test.code", + "line": 177 + }, + "16": { + "filename": "./test.code", + "line": 178 + }, + "24": { + "filename": "./test.code", + "line": 179 + }, + "40": { + "filename": "./test.code", + "line": 180 + }, + "56": { + "filename": "./test.code", + "line": 181 + }, + "72": { + "filename": "./test.code", + "line": 182 + }, + "80": { + "filename": "./test.code", + "line": 183 + }, + "88": { + "filename": "./test.code", + "line": 184 + }, + "112": { + "filename": "./test.code", + "line": 185 + }, + "136": { + "filename": "./test.code", + "line": 186 + }, + "144": { + "filename": "./test.code", + "line": 187 + }, + "152": { + "filename": "./test.code", + "line": 188 + }, + "168": { + "filename": "./test.code", + "line": 189 + }, + "184": { + "filename": "./test.code", + "line": 193 + }, + "192": { + "filename": "./test.code", + "line": 194 + }, + "216": { + "filename": "./test.code", + "line": 195 + }, + "232": { + "filename": "./test.code", + "line": 196 + }, + "240": { + "filename": "./test.code", + "line": 197 + }, + "256": { + "filename": "./test.code", + "line": 201 + }, + "264": { + "filename": "./test.code", + "line": 202 + }, + "280": { + "filename": "./test.code", + "line": 205 + } + }, + "c96102003281e57d347d103a62949116a408411163dcf6097818ced3a67ef913": { + "0": { + "filename": "", + "line": 1 + }, + "8": { + "filename": "", + "line": 2 + }, + "24": { + "filename": "", + "line": 3 + }, + "32": { + "filename": "", + "line": 4 + }, + "48": { + "filename": "", + "line": 5 + }, + "56": { + "filename": "", + "line": 6 + }, + "72": { + "filename": "", + "line": 7 + }, + "88": { + "filename": "", + "line": 8 + }, + "96": { + "filename": "", + "line": 9 + }, + "112": { + "filename": "", + "line": 10 + }, + "128": { + "filename": "", + "line": 11 + } + }, + "d4aaaeb571ca4586f4e7dffdd1ae4471fc53f06ec0af1cf61e45868ad9efa8fd": { + "0": { + "filename": "test.sol", + "line": 7 + }, + "8": { + "filename": "test.sol", + "line": 7 + }, + "24": { + "filename": "test.sol", + "line": 7 + }, + "32": { + "filename": "test.sol", + "line": 7 + }, + "40": { + "filename": "test.sol", + "line": 7 + }, + "48": { + "filename": "test.sol", + "line": 7 + }, + "56": { + "filename": "test.sol", + "line": 7 + }, + "64": { + "filename": "test.sol", + "line": 7 + }, + "72": { + "filename": "test.sol", + "line": 7 + }, + "88": { + "filename": "test.sol", + "line": 7 + }, + "96": { + "filename": "test.sol", + "line": 7 + }, + "120": { + "filename": "test.sol", + "line": 8 + } + }, + "d508a8f556c4eed66ae5dcb87e3a03906950dca6b075ffd8fbb523619aa60360": { + "0": { + "filename": "./test.code", + "line": 209 + }, + "16": { + "filename": "./test.code", + "line": 210 + }, + "24": { + "filename": "./test.code", + "line": 211 + }, + "40": { + "filename": "./test.code", + "line": 212 + }, + "56": { + "filename": "./test.code", + "line": 213 + }, + "72": { + "filename": "./test.code", + "line": 214 + }, + "80": { + "filename": "./test.code", + "line": 215 + }, + "96": { + "filename": "./test.code", + "line": 218 + }, + "112": { + "filename": "./test.code", + "line": 219 + }, + "120": { + "filename": "./test.code", + "line": 220 + }, + "136": { + "filename": "./test.code", + "line": 221 + }, + "152": { + "filename": "./test.code", + "line": 222 + }, + "168": { + "filename": "./test.code", + "line": 223 + }, + "176": { + "filename": "./test.code", + "line": 224 + }, + "192": { + "filename": "./test.code", + "line": 225 + }, + "200": { + "filename": "./test.code", + "line": 226 + }, + "208": { + "filename": "./test.code", + "line": 227 + }, + "216": { + "filename": "./test.code", + "line": 228 + }, + "224": { + "filename": "./test.code", + "line": 229 + }, + "240": { + "filename": "./test.code", + "line": 230 + }, + "248": { + "filename": "./test.code", + "line": 231 + }, + "264": { + "filename": "./test.code", + "line": 232 + }, + "272": { + "filename": "./test.code", + "line": 233 + }, + "288": { + "filename": "./test.code", + "line": 234 + }, + "304": { + "filename": "./test.code", + "line": 235 + }, + "320": { + "filename": "./test.code", + "line": 237 + }, + "328": { + "filename": "./test.code", + "line": 238 + }, + "344": { + "filename": "./test.code", + "line": 239 + }, + "352": { + "filename": "stdlib.sol", + "line": 61 + }, + "368": { + "filename": "stdlib.sol", + "line": 61 + }, + "376": { + "filename": "stdlib.sol", + "line": 61 + }, + "384": { + "filename": "stdlib.sol", + "line": 61 + }, + "400": { + "filename": "stdlib.sol", + "line": 62 + }, + "408": { + "filename": "stdlib.sol", + "line": 62 + }, + "424": { + "filename": "stdlib.sol", + "line": 62 + }, + "448": { + "filename": "stdlib.sol", + "line": 62 + }, + "456": { + "filename": "stdlib.sol", + "line": 62 + }, + "496": { + "filename": "stdlib.sol", + "line": 62 + }, + "504": { + "filename": "stdlib.sol", + "line": 62 + }, + "512": { + "filename": "stdlib.sol", + "line": 62 + }, + "528": { + "filename": "stdlib.sol", + "line": 63 + }, + "544": { + "filename": "./test.code", + "line": 241 + }, + "560": { + "filename": "./test.code", + "line": 242 + }, + "568": { + "filename": "./test.code", + "line": 243 + }, + "584": { + "filename": "./test.code", + "line": 244 + }, + "592": { + "filename": "./test.code", + "line": 245 + }, + "608": { + "filename": "./test.code", + "line": 246 + }, + "624": { + "filename": "./test.code", + "line": 247 + }, + "632": { + "filename": "./test.code", + "line": 248 + }, + "648": { + "filename": "./test.code", + "line": 251 + } + }, + "e0fb053e4efba3f353da19e00bb5b950022c182d07a4d306f45f33c21dca9b90": { + "0": { + "filename": "./test.code", + "line": 254 + }, + "8": { + "filename": "./test.code", + "line": 255 + }, + "56": { + "filename": "./test.code", + "line": 256 + }, + "64": { + "filename": "./test.code", + "line": 257 + }, + "80": { + "filename": "./test.code", + "line": 260 + }, + "88": { + "filename": "./test.code", + "line": 261 + }, + "136": { + "filename": "./test.code", + "line": 262 + }, + "144": { + "filename": "./test.code", + "line": 263 + }, + "160": { + "filename": "./test.code", + "line": 266 + }, + "168": { + "filename": "./test.code", + "line": 267 + }, + "216": { + "filename": "./test.code", + "line": 268 + }, + "224": { + "filename": "./test.code", + "line": 269 + } + }, + "f24e1e7aa04d89aad2945816b6e9b921f2b3892da9ba53e2383c148351b96d0c": { + "0": { + "filename": "./test.code", + "line": 190 + }, + "16": { + "filename": "./test.code", + "line": 191 + } + }, + "f2b6fee906959c240bebf2ae6014f1d4be66e2dc6e03df25aa5ea29205d3e249": { + "0": { + "filename": "./test.code", + "line": 118 + }, + "16": { + "filename": "./test.code", + "line": 119 + }, + "24": { + "filename": "./test.code", + "line": 120 + }, + "40": { + "filename": "./test.code", + "line": 121 + }, + "56": { + "filename": "./test.code", + "line": 122 + }, + "72": { + "filename": "./test.code", + "line": 123 + }, + "80": { + "filename": "./test.code", + "line": 124 + }, + "88": { + "filename": "./test.code", + "line": 125 + }, + "104": { + "filename": "./test.code", + "line": 126 + } + } + } +} diff --git a/tests/samples/test.sol b/tests/samples/test.sol new file mode 100644 index 00000000..4a35ce48 --- /dev/null +++ b/tests/samples/test.sol @@ -0,0 +1,18 @@ +pragma ever-solidity >= 0.64.0; +pragma AbiHeader expire; + +contract Test { + + modifier checkOwnerAndAccept { + require(msg.pubkey() == tvm.pubkey(), 102); + tvm.accept(); + _; + } + + function test(uint ctype, string data) public checkOwnerAndAccept { + } + + function get(uint ctype, string data) public returns (uint) { + return ctype + 1; + } +} diff --git a/tests/samples/test.tvc b/tests/samples/test.tvc new file mode 100644 index 0000000000000000000000000000000000000000..94ae483149beff84085c72d57d65d856499aba2f GIT binary patch literal 475 zcmdn`ZcY&+lQ1I#<9P-qMiXX6M#ck749*uA2ml2Zm9DqJ3Xho;4*Y-2q;TNhW2R5s z0<0`TOv~Q7T)6IenDIxN;%%GD42*r^%^cSy6nkDgx!xz3!d#`i<|B+PiBl$5eA9Egt9g2N2$`>v( z{&FxdJaN8V;arnI573$Cxf@UaKUwgbVWPn!uq$|Z7-W7p|8P2S`u}PB^UWvUhA^-g zEMbrX+H?8;W&6tvh8KS%|43rs0{ekU;L8$)FMB^7@Dmbb5Gl^jQ83UmGu1O-U;qF( CU&xyP literal 0 HcmV?d00001 diff --git a/tests/test_cli.rs b/tests/test_cli.rs index 16d3cd01..52f350b3 100644 --- a/tests/test_cli.rs +++ b/tests/test_cli.rs @@ -2626,9 +2626,47 @@ fn test_alternative_syntax() -> Result<(), Box> { cmd.assert() .success(); + let test_tvc = "tests/samples/test.tvc"; + let test_abi = "tests/samples/test.abi.json"; + let address = deploy_contract(key_path, test_tvc, test_abi, "{}")?; + + let mut cmd = Command::cargo_bin(BIN_NAME)?; + cmd.arg("runx") + .arg("--addr") + .arg(&address) + .arg("-m") + .arg("get") + .arg("--abi") + .arg(test_abi) + .arg("--data") + .arg("ctype") + .arg("--ctype") + .arg("14") + .assert() + .success() + .stdout(predicate::str::contains("Succeeded.")) + .stdout(predicate::str::contains("Result: {")) + .stdout(predicate::str::contains(r#""value0": "0x000000000000000000000000000000000000000000000000000000000000000f"#)); + + let mut cmd = Command::cargo_bin(BIN_NAME)?; + cmd.arg("callx") + .arg("--keys") + .arg(key_path) + .arg("--abi") + .arg(test_abi) + .arg("--addr") + .arg(&address) + .arg("-m") + .arg("test") + .arg("--data") + .arg("ctype") + .arg("--ctype") + .arg("14"); + cmd.assert() + .success(); + fs::remove_file(config_path)?; fs::remove_file(key_path)?; - Ok(()) } @@ -3205,3 +3243,5 @@ fn test_alternative_paths() -> Result<(), Box> { Ok(()) } + + From 9a73ac5c3a8a5bbee50ff51dd9aebd3107ff13ad Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Tue, 4 Oct 2022 16:53:17 +0400 Subject: [PATCH 03/12] Increased version --- Cargo.lock | 6 +++--- Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c9e55e02..5ece01f9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2023,9 +2023,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.9.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fd0db749597d91ff862fd1d55ea87f7855a744a8425a64695b6fca237d1dad1" +checksum = "a507befe795404456341dfab10cef66ead4c041f62b8b11bbb92bffe5d0953e0" [[package]] name = "socket2" @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "tonos-cli" -version = "0.28.13" +version = "0.28.15" dependencies = [ "assert_cmd", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index 6d4d8424..d2efc1f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ license = 'Apache-2.0' name = 'tonos-cli' readme = 'README.md' repository = 'https://github.com/tonlabs/tonos-cli' -version = '0.28.14' +version = '0.28.15' [dependencies] async-trait = '0.1.42' From 787b9de465f59ab064ee33e2e3a9a77f0d81c8cd Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Tue, 4 Oct 2022 19:21:04 +0400 Subject: [PATCH 04/12] Added file download timeout --- src/helpers.rs | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 26752f32..225441c4 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -15,7 +15,7 @@ use std::path::PathBuf; use crate::config::Config; use std::sync::Arc; -use std::time::SystemTime; +use std::time::{Duration, SystemTime}; use ton_client::abi::{ Abi, AbiConfig, AbiContract, DecodedMessageBody, DeploySet, ParamsOfDecodeMessageBody, ParamsOfEncodeMessage, Signer, @@ -43,6 +43,8 @@ pub const SDK_EXECUTION_ERROR_CODE: u32 = 414; const CONFIG_BASE_NAME: &str = "tonos-cli.conf.json"; const GLOBAL_CONFIG_PATH: &str = ".tonos-cli.global.conf.json"; +const FILE_LOAD_TIMEOUT: u64 = 60; // default file loading timeout in seconds + pub fn default_config_name() -> String { env::current_dir() .map(|dir| { @@ -320,13 +322,20 @@ pub async fn load_ton_abi(abi_path: &str) -> Result { } pub async fn load_file_with_url(url: &str) -> Result, String> { - let response = reqwest::get(url) + let client = reqwest::Client::builder() + .timeout(Duration::from_secs(FILE_LOAD_TIMEOUT)) + .build() + .map_err(|e| format!("Failed to create client: {e}"))?; + let res = client + .get(url) + .send() .await - .map_err(|e| format!("Failed to download the file data: {}", e))?; - let responce_bytes = response.bytes() + .map_err(|e| format!("Failed to send get request: {e}"))? + .bytes() .await - .map_err(|e| format!("Failed to decode network response: {}", e))?; - Ok(responce_bytes.to_vec()) + .map_err(|e| format!("Failed to get response bytes: {e}"))?; + Ok(res.to_vec()) + } From 3de6b8794de6142e874c6bcf30b7fc0ad3382c3f Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Tue, 4 Oct 2022 19:23:32 +0400 Subject: [PATCH 05/12] Increased version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ece01f9..7490aead 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "tonos-cli" -version = "0.28.15" +version = "0.28.16" dependencies = [ "assert_cmd", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index d2efc1f6..f634e957 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ license = 'Apache-2.0' name = 'tonos-cli' readme = 'README.md' repository = 'https://github.com/tonlabs/tonos-cli' -version = '0.28.15' +version = '0.28.16' [dependencies] async-trait = '0.1.42' From a76c551ebf89460bda98ebd84aada0945a6a1016 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Wed, 5 Oct 2022 14:37:11 +0400 Subject: [PATCH 06/12] Timeout from config --- README.md | 4 ++-- src/call.rs | 12 ++++++------ src/debot/term_browser.rs | 3 ++- src/debug.rs | 19 ++++++++++--------- src/decode.rs | 31 +++++++++++++++++-------------- src/deploy.rs | 18 ++++++++++-------- src/depool.rs | 8 +++++--- src/genaddr.rs | 4 ++-- src/helpers.rs | 27 ++++++++++++++------------- src/main.rs | 4 ++-- src/message.rs | 2 +- src/multisig.rs | 10 +++++----- src/run.rs | 2 +- src/voting.rs | 3 ++- 14 files changed, 79 insertions(+), 68 deletions(-) diff --git a/README.md b/README.md index 6f2661fb..6659c218 100644 --- a/README.md +++ b/README.md @@ -228,7 +228,7 @@ complete -C __tonos-cli_completion tonos-cli ``` After adding completion script, user can use `` key to complete `--addr` option with aliases saved in the config -file and `-m/--method` option with methods loaded from the abi file. +file and `-m/--method` option with methods loaded from the ABI file. ### Windows debug build troubleshooting @@ -355,7 +355,7 @@ List of available options: --project_id Project Id in Evercloud (dashboard.evercloud.dev). --pubkey User public key. Used by DeBot Browser. --retries Number of attempts to call smart contract function if previous attempt was unsuccessful. ---timeout Network `wait_for` timeout in ms. +--timeout Network `wait_for` timeout in ms. This value is also used as timeout for remote files (specified with link, e.g. ABI file) loading. --url Url to connect. --wallet Multisig wallet address. --wc Workchain id. diff --git a/src/call.rs b/src/call.rs index d62567e1..ef7812c5 100644 --- a/src/call.rs +++ b/src/call.rs @@ -68,8 +68,8 @@ fn parse_integer_param(value: &str) -> Result { } } -async fn build_json_from_params(params_vec: Vec<&str>, abi_path: &str, method: &str) -> Result { - let abi_obj = load_ton_abi(abi_path).await?; +async fn build_json_from_params(params_vec: Vec<&str>, abi_path: &str, method: &str, config: &Config) -> Result { + let abi_obj = load_ton_abi(abi_path, config).await?; let functions = abi_obj.functions(); let func_obj = functions.get(method).ok_or("failed to load function from abi")?; @@ -282,7 +282,7 @@ pub async fn call_contract_with_client( is_fee: bool, matches: Option<&ArgMatches<'_>>, ) -> Result { - let abi = load_abi(abi_path).await?; + let abi = load_abi(abi_path, config).await?; let msg_params = prepare_message_params( addr, @@ -400,7 +400,7 @@ pub async fn call_contract( pub async fn call_contract_with_msg(config: &Config, str_msg: String, abi_path: &str) -> Result<(), String> { let ton = create_client_verbose(&config)?; - let abi = load_abi(abi_path).await?; + let abi = load_abi(abi_path, config).await?; let (msg, _) = unpack_message(&str_msg)?; if config.is_json { @@ -431,11 +431,11 @@ pub async fn call_contract_with_msg(config: &Config, str_msg: String, abi_path: Ok(()) } -pub async fn parse_params(params_vec: Vec<&str>, abi_path: &str, method: &str) -> Result { +pub async fn parse_params(params_vec: Vec<&str>, abi_path: &str, method: &str, config: &Config) -> Result { if params_vec.len() == 1 { // if there is only 1 parameter it must be a json string with arguments Ok(params_vec[0].to_owned()) } else { - build_json_from_params(params_vec, abi_path, method).await + build_json_from_params(params_vec, abi_path, method, config).await } } diff --git a/src/debot/term_browser.rs b/src/debot/term_browser.rs index cecc6253..616e18bc 100644 --- a/src/debot/term_browser.rs +++ b/src/debot/term_browser.rs @@ -114,7 +114,8 @@ impl TerminalBrowser { let info: DebotInfo = dengine.init().await?.into(); let abi_version = info.dabi_version.clone(); let abi_ref = info.dabi.as_ref(); - let abi = load_abi(abi_ref.ok_or("DeBot ABI is not defined".to_string())?).await?; + let def_config = Config::default(); + let abi = load_abi(abi_ref.ok_or("DeBot ABI is not defined".to_string())?, &def_config).await?; if !autorun { Self::print_info(&info); } diff --git a/src/debug.rs b/src/debug.rs index ff5140a3..4cc03893 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -445,7 +445,7 @@ async fn debug_transaction_command(matches: &ArgMatches<'_>, config: &Config, is !matches.is_present("IGNORE_HASHES"), ).await?; - decode_messages(tr.out_msgs, load_decode_abi(matches, config)).await?; + decode_messages(tr.out_msgs, load_decode_abi(matches, config), config).await?; if !config.is_json { println!("Log saved to {}.", trace_path); } else { @@ -535,7 +535,7 @@ async fn replay_transaction_command(matches: &ArgMatches<'_>, config: &Config) - match result_trans { Ok(result_trans) => { - decode_messages(result_trans.out_msgs,load_decode_abi(matches, config)).await?; + decode_messages(result_trans.out_msgs,load_decode_abi(matches, config), config).await?; if !config.is_json { println!("Execution finished."); } @@ -586,7 +586,7 @@ async fn debug_call_command(matches: &ArgMatches<'_>, full_config: &FullConfig, .ok_or("Method is not defined. Supply it in the config file or command line.")?); let is_boc = matches.is_present("BOC"); let is_tvc = matches.is_present("TVC"); - let loaded_abi = load_abi(opt_abi.as_ref().unwrap()).await?; + let loaded_abi = load_abi(opt_abi.as_ref().unwrap(), &full_config.config).await?; let params = unpack_alternative_params( matches, opt_abi.as_ref().unwrap(), @@ -680,7 +680,7 @@ async fn debug_call_command(matches: &ArgMatches<'_>, full_config: &FullConfig, let mut out_res = vec![]; let msg_string = match trans { Ok(trans) => { - out_res = decode_messages(trans.out_msgs,load_decode_abi(matches, &full_config.config)).await?; + out_res = decode_messages(trans.out_msgs,load_decode_abi(matches, &full_config.config), &full_config.config).await?; "Execution finished.".to_string() } Err(e) => { @@ -779,7 +779,7 @@ async fn debug_message_command(matches: &ArgMatches<'_>, config: &Config) -> Res let msg_string = match trans { Ok(trans) => { - decode_messages(trans.out_msgs,load_decode_abi(matches, config)).await?; + decode_messages(trans.out_msgs,load_decode_abi(matches, config), config).await?; "Execution finished.".to_string() } Err(e) => { @@ -831,7 +831,8 @@ async fn debug_deploy_command(matches: &ArgMatches<'_>, config: &Config) -> Resu opt_abi.as_ref().unwrap(), params.as_ref().unwrap(), sign, - wc.unwrap() + wc.unwrap(), + config ).await?; let init_balance = matches.is_present("INIT_BALANCE"); let ton_client = create_client(config)?; @@ -887,7 +888,7 @@ async fn debug_deploy_command(matches: &ArgMatches<'_>, config: &Config) -> Resu let msg_string = match trans { Ok(trans) => { - decode_messages(trans.out_msgs,load_decode_abi(matches, config)).await?; + decode_messages(trans.out_msgs,load_decode_abi(matches, config), config).await?; "Execution finished.".to_string() } Err(e) => { @@ -904,7 +905,7 @@ async fn debug_deploy_command(matches: &ArgMatches<'_>, config: &Config) -> Resu Ok(()) } -async fn decode_messages(msgs: OutMessages, abi: Option) -> Result, String> { +async fn decode_messages(msgs: OutMessages, abi: Option, config: &Config) -> Result, String> { if !msgs.is_empty() { log::debug!(target: "executor", "Output messages:\n----------------"); } @@ -913,7 +914,7 @@ async fn decode_messages(msgs: OutMessages, abi: Option) -> Result, config: &Config) -> Result<(), if !config.is_json { print_args!(body, abi); } - decode_body(body.unwrap(), &abi.unwrap(), config.is_json).await?; + decode_body(body.unwrap(), &abi.unwrap(), config.is_json, config).await?; Ok(()) } @@ -251,7 +251,7 @@ async fn decode_tvc_fields(m: &ArgMatches<'_>, config: &Config) -> Result<(), St if !config.is_json { print_args!(tvc, abi); } - let abi = load_abi(abi.as_ref().unwrap()).await?; + let abi = load_abi(abi.as_ref().unwrap(), config).await?; let state = StateInit::construct_from_file(tvc.unwrap()) .map_err(|e| format!("failed to load StateInit from the tvc file: {}", e))?; let b64 = tree_of_cells_into_base64(state.data.as_ref())?; @@ -280,7 +280,7 @@ async fn decode_account_fields(m: &ArgMatches<'_>, config: &Config) -> Result<() if !config.is_json { print_args!(address, abi); } - let abi = load_abi(abi.as_ref().unwrap()).await?; + let abi = load_abi(abi.as_ref().unwrap(), config).await?; let ton = create_client_verbose(&config)?; let address = load_ton_address(address.unwrap(), &config)?; @@ -311,7 +311,7 @@ struct SortedFunctionHeader { expire: Option } -async fn decode_body(body_base64: &str, abi_path: &str, is_json: bool) -> Result<(), String> { +async fn decode_body(body_base64: &str, abi_path: &str, is_json: bool, config: &Config) -> Result<(), String> { let body_vec = base64::decode(body_base64) .map_err(|e| format!("body is not a valid base64 string: {}", e))?; @@ -325,9 +325,9 @@ async fn decode_body(body_base64: &str, abi_path: &str, is_json: bool) -> Result let ton = create_client_local()?; let (mut res, is_external) = { - match decode_msg_body(ton.clone(), abi_path, body_base64, false).await { + match decode_msg_body(ton.clone(), abi_path, body_base64, false, config).await { Ok(res) => (res, true), - Err(_) => (decode_msg_body(ton.clone(), abi_path, body_base64, true).await?, false), + Err(_) => (decode_msg_body(ton.clone(), abi_path, body_base64, true, config).await?, false), } }; let mut signature = None; @@ -345,7 +345,7 @@ async fn decode_body(body_base64: &str, abi_path: &str, is_json: bool) -> Result } } } - let contr = load_ton_abi(abi_path).await?; + let contr = load_ton_abi(abi_path, config).await?; let (_, func_id, _) = ton_abi::Function::decode_header(contr.version(), orig_slice.clone(), contr.header(), !is_external) .map_err(|e| format!("Failed to decode header: {}", e))?; @@ -379,7 +379,8 @@ async fn decode_body(body_base64: &str, abi_path: &str, is_json: bool) -> Result async fn decode_message(msg_boc: Vec, abi_path: Option) -> Result { let tvm_msg = ton_sdk::Contract::deserialize_message(&msg_boc[..]) .map_err(|e| format!("failed to deserialize message boc: {}", e))?; - let result = msg_printer::serialize_msg(&tvm_msg, abi_path).await?; + let config = Config::default(); + let result = msg_printer::serialize_msg(&tvm_msg, abi_path, &config).await?; Ok(serde_json::to_string_pretty(&result) .map_err(|e| format!("Failed to serialize the result: {}", e))?) } @@ -441,6 +442,7 @@ pub mod msg_printer { use ton_types::Cell; use crate::helpers::{TonClient, create_client_local, decode_msg_body}; use ton_client::boc::{get_compiler_version, ParamsOfGetCompilerVersion}; + use crate::Config; pub fn tree_of_cells_into_base64(root_cell: Option<&Cell>) -> Result { match root_cell { @@ -549,7 +551,7 @@ pub mod msg_printer { } } - pub async fn serialize_body(body_vec: Vec, abi_path: &str, ton: TonClient) -> Result { + pub async fn serialize_body(body_vec: Vec, abi_path: &str, ton: TonClient, config: &Config) -> Result { let mut empty_boc = vec![]; serialize_tree_of_cells(&Cell::default(), &mut empty_boc) .map_err(|e| format!("failed to serialize tree of cells: {}", e))?; @@ -558,16 +560,16 @@ pub mod msg_printer { } let body_base64 = base64::encode(&body_vec); let mut res = { - match decode_msg_body(ton.clone(), abi_path, &body_base64, false).await { + match decode_msg_body(ton.clone(), abi_path, &body_base64, false, config).await { Ok(res) => res, - Err(_) => decode_msg_body(ton.clone(), abi_path, &body_base64, true).await?, + Err(_) => decode_msg_body(ton.clone(), abi_path, &body_base64, true, config).await?, } }; let output = res.value.take().ok_or("failed to obtain the result")?; Ok(json!({res.name : output})) } - pub async fn serialize_msg(msg: &Message, abi_path: Option) -> Result { + pub async fn serialize_msg(msg: &Message, abi_path: Option, config: &Config) -> Result { let mut res = json!({ }); let ton = create_client_local()?; res["Type"] = serialize_msg_type(msg.header()); @@ -583,7 +585,7 @@ pub mod msg_printer { let mut body_vec = Vec::new(); serialize_tree_of_cells(&msg.body().unwrap().into_cell(), &mut body_vec) .map_err(|e| format!("failed to serialize body: {}", e))?; - res["BodyCall"] = match serialize_body(body_vec, &abi_path, ton).await { + res["BodyCall"] = match serialize_body(body_vec, &abi_path, ton, config).await { Ok(res) => res, Err(_) => { json!("Undefined") @@ -609,6 +611,7 @@ mod tests { #[tokio::test] async fn test_decode_body_json() { let body = "te6ccgEBAQEARAAAgwAAALqUCTqWL8OX7JivfJrAAzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMzMQAAAAAAAAAAAAAAAEeGjADA=="; - let _out = decode_body(body, "tests/samples/wallet.abi.json", true).await.unwrap(); + let config = Config::default(); + let _out = decode_body(body, "tests/samples/wallet.abi.json", true, &config).await.unwrap(); } } diff --git a/src/deploy.rs b/src/deploy.rs index d3dc850e..e3946f8f 100644 --- a/src/deploy.rs +++ b/src/deploy.rs @@ -22,6 +22,7 @@ use ton_client::abi::{ encode_message, Signer, CallSet, DeploySet, ParamsOfEncodeMessage, Abi, }; use ton_client::crypto::KeyPair; +use crate::Config; use crate::message::{display_generated_message, EncodedMessage}; pub async fn deploy_contract( @@ -41,7 +42,7 @@ pub async fn deploy_contract( println!("Deploying..."); } - let (msg, addr) = prepare_deploy_message(tvc, abi, params, keys_file.clone(), wc).await?; + let (msg, addr) = prepare_deploy_message(tvc, abi, params, keys_file.clone(), wc, &full_config.config).await?; let enc_msg = encode_message(ton.clone(), msg.clone()).await .map_err(|e| format!("failed to create inbound message: {}", e))?; @@ -54,7 +55,7 @@ pub async fn deploy_contract( } if config.async_call { - let abi = load_abi(&abi).await?; + let abi = load_abi(&abi, config).await?; send_message_and_wait(ton, Some(abi), enc_msg.message, @@ -86,12 +87,12 @@ pub async fn generate_deploy_message( wc: i32, is_raw: bool, output: Option<&str>, - is_json: bool, + config: &Config, ) -> Result<(), String> { let ton = create_client_local()?; - let (msg, addr) = prepare_deploy_message(tvc, abi, params, keys_file, wc).await?; + let (msg, addr) = prepare_deploy_message(tvc, abi, params, keys_file, wc, config).await?; let msg = encode_message(ton, msg).await .map_err(|e| format!("failed to create inbound message: {}", e))?; @@ -101,8 +102,8 @@ pub async fn generate_deploy_message( expire: None, address: addr.to_owned(), }; - display_generated_message(&msg, "constructor", is_raw, output, is_json)?; - if !is_json { + display_generated_message(&msg, "constructor", is_raw, output, config.is_json)?; + if !config.is_json { println!("Contract's address: {}", addr); println!("Succeeded."); } @@ -114,9 +115,10 @@ pub async fn prepare_deploy_message( abi: &str, params: &str, keys_file: Option, - wc: i32 + wc: i32, + config: &Config, ) -> Result<(ParamsOfEncodeMessage, String), String> { - let abi = load_abi(abi).await?; + let abi = load_abi(abi, config).await?; let keys = keys_file.map(|k| load_keypair(&k)).transpose()?; diff --git a/src/depool.rs b/src/depool.rs index cb8c5b58..36ac9ad4 100644 --- a/src/depool.rs +++ b/src/depool.rs @@ -400,10 +400,11 @@ async fn print_event(ton: TonClient, event: &serde_json::Value) -> Result<(), St let body = event["body"].as_str() .ok_or("failed to serialize event body")?; + let def_config = Config::default(); let result = ton_client::abi::decode_message_body( ton.clone(), ParamsOfDecodeMessageBody { - abi: load_abi(DEPOOL_ABI).await.map_err(|e| format!("failed to load depool abi: {}", e))?, + abi: load_abi(DEPOOL_ABI, &def_config).await.map_err(|e| format!("failed to load depool abi: {}", e))?, body: body.to_owned(), is_internal: false, ..Default::default() @@ -690,10 +691,11 @@ async fn set_donor( async fn encode_body(func: &str, params: serde_json::Value) -> Result { let client = create_client_local()?; + let def_config = Config::default(); ton_client::abi::encode_message_body( client.clone(), ParamsOfEncodeMessageBody { - abi: load_abi(DEPOOL_ABI).await?, + abi: load_abi(DEPOOL_ABI, &def_config).await?, call_set: CallSet::some_with_function_and_input(func, params) .ok_or("failed to create CallSet with specified parameters.")?, is_internal: true, @@ -819,7 +821,7 @@ async fn call_contract_and_get_answer( answer_is_expected: bool ) -> Result<(), String> { let ton = create_client_verbose(&config)?; - let abi = load_abi(MSIG_ABI).await?; + let abi = load_abi(MSIG_ABI, config).await?; let start = now()?; let params = json!({ diff --git a/src/genaddr.rs b/src/genaddr.rs index 77c68dbc..0d7d2753 100644 --- a/src/genaddr.rs +++ b/src/genaddr.rs @@ -31,7 +31,7 @@ pub async fn generate_address( let contract = std::fs::read(tvc) .map_err(|e| format!("failed to read smart contract file: {}", e))?; - let abi = load_abi(abi_path).await?; + let abi = load_abi(abi_path, config).await?; let phrase = if new_keys { gen_seed_phrase()? @@ -79,7 +79,7 @@ pub async fn generate_address( vec![0; 32] } }; - let abi_str = load_abi_str(abi_path).await?; + let abi_str = load_abi_str(abi_path, config).await?; update_contract_state(tvc, &key_bytes, initial_data, &abi_str)?; if !config.is_json { println!("TVC file updated"); diff --git a/src/helpers.rs b/src/helpers.rs index 225441c4..7487c793 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -43,8 +43,6 @@ pub const SDK_EXECUTION_ERROR_CODE: u32 = 414; const CONFIG_BASE_NAME: &str = "tonos-cli.conf.json"; const GLOBAL_CONFIG_PATH: &str = ".tonos-cli.global.conf.json"; -const FILE_LOAD_TIMEOUT: u64 = 60; // default file loading timeout in seconds - pub fn default_config_name() -> String { env::current_dir() .map(|dir| { @@ -279,8 +277,10 @@ pub async fn decode_msg_body( abi_path: &str, body: &str, is_internal: bool, + config: &Config, ) -> Result { - let abi = load_abi(abi_path).await?; + + let abi = load_abi(abi_path, config).await?; ton_client::abi::decode_message_body( ton, ParamsOfDecodeMessageBody { @@ -294,13 +294,13 @@ pub async fn decode_msg_body( .map_err(|e| format!("failed to decode body: {}", e)) } -pub async fn load_abi_str(abi_path: &str) -> Result { +pub async fn load_abi_str(abi_path: &str, config: &Config) -> Result { let abi_from_json = serde_json::from_str::(abi_path); if abi_from_json.is_ok() { return Ok(abi_path.to_string()); } if Url::parse(abi_path).is_ok() { - let abi_bytes = load_file_with_url(abi_path).await?; + let abi_bytes = load_file_with_url(abi_path, config.timeout as u64).await?; return Ok(String::from_utf8(abi_bytes) .map_err(|e| format!("Downloaded string contains not valid UTF8 characters: {}", e))?); } @@ -308,22 +308,22 @@ pub async fn load_abi_str(abi_path: &str) -> Result { .map_err(|e| format!("failed to read ABI file: {}", e))?) } -pub async fn load_abi(abi_path: &str) -> Result { - let abi_str = load_abi_str(abi_path).await?; +pub async fn load_abi(abi_path: &str, config: &Config) -> Result { + let abi_str = load_abi_str(abi_path, config).await?; Ok(Contract(serde_json::from_str::(&abi_str) .map_err(|e| format!("ABI is not a valid json: {}", e))?, )) } -pub async fn load_ton_abi(abi_path: &str) -> Result { - let abi_str = load_abi_str(abi_path).await?; +pub async fn load_ton_abi(abi_path: &str, config: &Config) -> Result { + let abi_str = load_abi_str(abi_path, config).await?; Ok(ton_abi::Contract::load(abi_str.as_bytes()) .map_err(|e| format!("Failed to load ABI: {}", e))?) } -pub async fn load_file_with_url(url: &str) -> Result, String> { +pub async fn load_file_with_url(url: &str, timeout: u64) -> Result, String> { let client = reqwest::Client::builder() - .timeout(Duration::from_secs(FILE_LOAD_TIMEOUT)) + .timeout(Duration::from_millis(timeout)) .build() .map_err(|e| format!("Failed to create client: {e}"))?; let res = client @@ -411,10 +411,11 @@ pub async fn print_message(ton: TonClient, message: &Value, abi: &str, is_intern let body = message["body"].as_str(); if body.is_some() { let body = body.unwrap(); + let def_config = Config::default(); let result = ton_client::abi::decode_message_body( ton.clone(), ParamsOfDecodeMessageBody { - abi: load_abi(abi).await?, + abi: load_abi(abi, &def_config).await?, body: body.to_owned(), is_internal, ..Default::default() @@ -660,7 +661,7 @@ pub fn load_params(params: &str) -> Result { pub async fn unpack_alternative_params(matches: &ArgMatches<'_>, abi_path: &str, method: &str, config: &Config) -> Result, String> { if matches.is_present("PARAMS") { let params = matches.values_of("PARAMS").unwrap().collect::>(); - Ok(Some(parse_params(params, abi_path, method).await?)) + Ok(Some(parse_params(params, abi_path, method, config).await?)) } else { Ok(config.parameters.clone().or(Some("{}".to_string()))) } diff --git a/src/main.rs b/src/main.rs index 903cf264..01b91885 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1170,7 +1170,7 @@ async fn body_command(matches: &ArgMatches<'_>, config: &Config) -> Result<(), S let body = ton_client::abi::encode_message_body( client.clone(), ParamsOfEncodeMessageBody { - abi: load_abi(abi.as_ref().unwrap()).await?, + abi: load_abi(abi.as_ref().unwrap(), config).await?, call_set: CallSet::some_with_function_and_input(method.unwrap(), params) .ok_or("failed to create CallSet with specified parameters.")?, is_internal: true, @@ -1326,7 +1326,7 @@ async fn deploy_command(matches: &ArgMatches<'_>, full_config: &mut FullConfig, } match deploy_type { DeployType::Full => deploy_contract(full_config, tvc.unwrap(), &abi.unwrap(), ¶ms.unwrap(), keys, wc, false, alias).await, - DeployType::MsgOnly => generate_deploy_message(tvc.unwrap(), &abi.unwrap(), ¶ms.unwrap(), keys, wc, raw, output, config.is_json).await, + DeployType::MsgOnly => generate_deploy_message(tvc.unwrap(), &abi.unwrap(), ¶ms.unwrap(), keys, wc, raw, output, config).await, DeployType::Fee => deploy_contract(full_config, tvc.unwrap(), &abi.unwrap(), ¶ms.unwrap(), keys, wc, true, None).await, } } diff --git a/src/message.rs b/src/message.rs index d74f180d..4a7f9845 100644 --- a/src/message.rs +++ b/src/message.rs @@ -166,7 +166,7 @@ pub async fn generate_message( let ton_addr = load_ton_address(addr, &config) .map_err(|e| format!("failed to parse address: {}", e.to_string()))?; - let abi = load_abi(abi).await?; + let abi = load_abi(abi, config).await?; let expire_at = lifetime + now()?; let header = FunctionHeader { diff --git a/src/multisig.rs b/src/multisig.rs index 68667423..c55cc47a 100644 --- a/src/multisig.rs +++ b/src/multisig.rs @@ -260,10 +260,10 @@ async fn multisig_send_command(matches: &ArgMatches<'_>, config: &Config) -> Res send(config, address.as_str(), dest, value, keys, comment).await } -pub async fn encode_transfer_body(text: &str) -> Result { +pub async fn encode_transfer_body(text: &str, config: &Config) -> Result { let text = hex::encode(text.as_bytes()); let client = create_client_local()?; - let abi = load_abi(TRANSFER_WITH_COMMENT).await?; + let abi = load_abi(TRANSFER_WITH_COMMENT, config).await?; encode_message_body( client.clone(), ParamsOfEncodeMessageBody { @@ -289,7 +289,7 @@ async fn send( comment: Option<&str> ) -> Result<(), String> { let body = if let Some(text) = comment { - encode_transfer_body(text).await? + encode_transfer_body(text, config).await? } else { "".to_owned() }; @@ -339,8 +339,8 @@ async fn multisig_deploy_command(matches: &ArgMatches<'_>, config: &Config) -> R SAFEMULTISIG_LINK }; - let tvc_bytes = load_file_with_url(target).await?; - let abi = load_abi(MSIG_ABI).await?; + let tvc_bytes = load_file_with_url(target, config.timeout as u64).await?; + let abi = load_abi(MSIG_ABI, config).await?; let keys = load_keypair(&keys)?; diff --git a/src/run.rs b/src/run.rs index 87a7bf57..921e534d 100644 --- a/src/run.rs +++ b/src/run.rs @@ -104,7 +104,7 @@ async fn run( } }; - let abi = load_abi(&abi_path).await?; + let abi = load_abi(&abi_path, config).await?; let params = if is_alternative { unpack_alternative_params(matches, &abi_path, method, config).await? } else { diff --git a/src/voting.rs b/src/voting.rs index d96ecdeb..587dadfa 100644 --- a/src/voting.rs +++ b/src/voting.rs @@ -25,7 +25,7 @@ pub async fn create_proposal( offline: bool, ) -> Result<(), String> { - let payload = encode_transfer_body(text).await?; + let payload = encode_transfer_body(text, config).await?; let params = json!({ "dest": dest, @@ -138,6 +138,7 @@ pub async fn decode_proposal( TRANSFER_WITH_COMMENT, body, true, + config, ) .await .map_err(|e| format!("failed to decode proposal payload: {}", e))?; From dd74a45087c2f9b004b81f1848c452b8af060486 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Wed, 5 Oct 2022 20:00:53 +0400 Subject: [PATCH 07/12] Fixed debug log with debug_on_fail flag --- README.md | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/debug.rs | 27 ++++++++++++++---- src/helpers.rs | 4 +-- 3 files changed, 97 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 6659c218..ed7b07ea 100644 --- a/README.md +++ b/README.md @@ -741,6 +741,80 @@ Config: /home/user/TONLabs/tonos-cli/tonos-cli.conf.json {} ``` +## 2.10. Enabling verbose mode for SDK execution + +User can increase log level of the tool execution to see more messages. To do it one need to specify environment +variable `RUST_LOG=debug`: + +```bash +$ tonos-cli callx --addr 0:75186644bf5157d1b638390889ec2ba297a12250f6e90d935618918cb82d12c3 --abi ../samples/1_Accumulator.abi.json --keys keys/key0 -m add --value 1 +Input arguments: + address: 0:75186644bf5157d1b638390889ec2ba297a12250f6e90d935618918cb82d12c3 + method: add + params: {"value":"1"} + abi: ../samples/1_Accumulator.abi.json + keys: keys/key0 +Connecting to: + Url: net.evercloud.dev + Endpoints: ["https://devnet.evercloud.dev/b2ad82504ee54fccb5bc6db8cbb3df1e"] + +MessageId: b3e24321924526dbfdc8ffdd9cc94aeb2da80edca7d87bd7f16f4a0a2afbfa20 +Succeeded. +Result: {} + +# Enable verbose mode +$ export RUST_LOG=debug + +$ tonos-cli callx --addr 0:75186644bf5157d1b638390889ec2ba297a12250f6e90d935618918cb82d12c3 --abi ../samples/1_Accumulator.abi.json --keys keys/key0 -m add --value 1 +Input arguments: + address: 0:75186644bf5157d1b638390889ec2ba297a12250f6e90d935618918cb82d12c3 + method: add + params: {"value":"1"} + abi: ../samples/1_Accumulator.abi.json + keys: keys/key0 +Connecting to: + Url: net.evercloud.dev + Endpoints: ["https://devnet.evercloud.dev/b2ad82504ee54fccb5bc6db8cbb3df1e"] + +starting new connection: https://devnet.evercloud.dev/ +Last block "76657141a65727996dadf9b929d40887cc3c78df09a97b9daecabd8b3e01327a" +MessageId: 64c98e8fbf5aa9ccf9d6526c6275bc617f6eb6f747b616f82e85cda7403c165b +message_expiration_time 1664983987 +fetch_block_timeout 88688 +1664983931: block received { + "id": "b3ab65d5b8503dedfa1250d72b7d8247e802551dfedabb80b82454abb6e755ce", + "gen_utime": 1664983924, + "after_split": false, + "workchain_id": 0, + "shard": "7800000000000000", + "in_msg_descr": [] +} +fetch_block_timeout 85461 +1664983933: block received { + "id": "8dc7cc2c4ab9be6b4ac0e9d3bcd6aac3179825683f4c8df02f76e9929a649ffc", + "gen_utime": 1664983926, + "after_split": false, + "workchain_id": 0, + "shard": "7800000000000000", + "in_msg_descr": [] +} +fetch_block_timeout 83209 +1664983936: block received { + "id": "b6977305cf28b86a0547a7fd34c03ad0534a94fb5453c3639e5f28e18a0c5d6b", + "gen_utime": 1664983929, + "after_split": false, + "workchain_id": 0, + "shard": "7800000000000000", + "in_msg_descr": [ + { + "msg_id": "64c98e8fbf5aa9ccf9d6526c6275bc617f6eb6f747b616f82e85cda7403c165b", + "transaction_id": "796ebf67fab053ea88bdf9a971d088fc6dbcb47b106f420c740815246f28c8b7" + } + ] +} +Succeeded. +Result: {} +``` # 3. Cryptographic commands diff --git a/src/debug.rs b/src/debug.rs index 4cc03893..8dc71966 100644 --- a/src/debug.rs +++ b/src/debug.rs @@ -10,12 +10,14 @@ * See the License for the specific TON DEV software governing permissions and * limitations under the License. */ -use crate::{contract_data_from_matches_or_config_alias, FullConfig, print_args, unpack_alternative_params}; +use crate::{contract_data_from_matches_or_config_alias, FullConfig, print_args, + unpack_alternative_params}; use clap::{ArgMatches, SubCommand, Arg, App}; use crate::config::Config; use crate::helpers::{load_ton_address, create_client, load_abi, now_ms, construct_account_from_tvc, TonClient, query_account_field, query_with_limit, create_client_verbose, - abi_from_matches_or_config, load_debug_info, wc_from_matches_or_config}; + abi_from_matches_or_config, load_debug_info, wc_from_matches_or_config, + TEST_MAX_LEVEL, MAX_LEVEL}; use crate::replay::{ fetch, CONFIG_ADDR, replay, DUMP_NONE, DUMP_CONFIG, DUMP_ACCOUNT, construct_blockchain_config }; @@ -47,6 +49,7 @@ const TRANSACTION_QUANTITY: u32 = 10; pub struct DebugLogger { tvm_trace: String, + ordinary_log_level: log::LevelFilter, } impl DebugLogger { @@ -58,6 +61,14 @@ impl DebugLogger { DebugLogger { tvm_trace: path, + ordinary_log_level: if std::env::var("RUST_LOG") + .unwrap_or_default() + .eq_ignore_ascii_case("debug") + { + TEST_MAX_LEVEL + } else { + MAX_LEVEL + }, } } } @@ -87,11 +98,15 @@ impl log::Log for DebugLogger { } } _ => { - match record.level() { - log::Level::Error | log::Level::Warn => { - eprintln!("{}", record.args()); + if record.level() <= self.ordinary_log_level { + match record.level() { + log::Level::Error | log::Level::Warn => { + eprintln!("{}", record.args()); + } + _ => { + println!("{}", record.args()); + } } - _ => {} } } } diff --git a/src/helpers.rs b/src/helpers.rs index 7487c793..47070db8 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -33,8 +33,8 @@ use url::Url; use crate::call::parse_params; use crate::FullConfig; -const TEST_MAX_LEVEL: log::LevelFilter = log::LevelFilter::Debug; -const MAX_LEVEL: log::LevelFilter = log::LevelFilter::Warn; +pub const TEST_MAX_LEVEL: log::LevelFilter = log::LevelFilter::Debug; +pub const MAX_LEVEL: log::LevelFilter = log::LevelFilter::Warn; pub const HD_PATH: &str = "m/44'/396'/0'/0/0"; pub const WORD_COUNT: u8 = 12; From e1d6ddbe135d68c16f3d6deb0d535601c5deef16 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Wed, 5 Oct 2022 20:12:52 +0400 Subject: [PATCH 08/12] Added endpoints count to config --- src/helpers.rs | 18 +++++++++++++++++- src/replay.rs | 36 ++++++++++-------------------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 47070db8..2daa09a7 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -22,7 +22,7 @@ use ton_client::abi::{ }; use ton_client::crypto::{CryptoConfig, KeyPair}; use ton_client::error::ClientError; -use ton_client::net::{query_collection, OrderBy, ParamsOfQueryCollection}; +use ton_client::net::{query_collection, OrderBy, ParamsOfQueryCollection, NetworkConfig}; use ton_client::{ClientConfig, ClientContext}; use ton_block::{Account, MsgAddressInt, Deserializable, CurrencyCollection, StateInit, Serializable}; use std::str::FromStr; @@ -139,6 +139,21 @@ pub fn get_server_endpoints(config: &Config) -> Vec { } } +pub fn get_network_context(config: &Config) -> Result, failure::Error> { + let endpoints = get_server_endpoints(config); + Ok(Arc::new( + ClientContext::new(ClientConfig { + network: NetworkConfig { + sending_endpoint_count: endpoints.len() as u8, + endpoints: Some(endpoints), + access_key: config.access_key.clone(), + ..Default::default() + }, + ..Default::default() + })? + )) +} + pub fn create_client(config: &Config) -> Result { let modified_endpoints = get_server_endpoints(config); if !config.is_json { @@ -158,6 +173,7 @@ pub fn create_client(config: &Config) -> Result { }, network: ton_client::net::NetworkConfig { server_address: Some(config.url.to_owned()), + sending_endpoint_count: modified_endpoints.len() as u8, endpoints: if modified_endpoints.is_empty() { None } else { diff --git a/src/replay.rs b/src/replay.rs index a22b6f32..4fb2d34f 100644 --- a/src/replay.rs +++ b/src/replay.rs @@ -22,17 +22,19 @@ use failure::err_msg; use serde::{Deserialize, Serialize}; use serde_json::Value; -use ton_block::{Account, ConfigParams, Deserializable, Message, Serializable, Transaction, TransactionDescr, Block, HashmapAugType}; +use ton_block::{Account, ConfigParams, Deserializable, Message, Serializable, Transaction, + TransactionDescr, Block, HashmapAugType}; use ton_client::{ - ClientConfig, ClientContext, - net::{AggregationFn, FieldAggregation, NetworkConfig, OrderBy, ParamsOfAggregateCollection, ParamsOfQueryCollection, SortDirection, aggregate_collection, query_collection}, + net::{AggregationFn, FieldAggregation, OrderBy, ParamsOfAggregateCollection, + ParamsOfQueryCollection, SortDirection, aggregate_collection, query_collection}, }; -use ton_executor::{BlockchainConfig, ExecuteParams, OrdinaryTransactionExecutor, TickTockTransactionExecutor, TransactionExecutor}; +use ton_executor::{BlockchainConfig, ExecuteParams, OrdinaryTransactionExecutor, + TickTockTransactionExecutor, TransactionExecutor}; use ton_types::{UInt256, serialize_tree_of_cells}; use ton_vm::executor::{Engine, EngineTraceInfo}; use crate::config::Config; -use crate::helpers::{create_client, get_server_endpoints, query_account_field}; +use crate::helpers::{create_client, get_network_context, query_account_field}; pub static CONFIG_ADDR: &str = "-1:5555555555555555555555555555555555555555555555555555555555555555"; @@ -62,17 +64,8 @@ pub async fn fetch(config: &Config, account_address: &str, filename: &str, fast_ } return Ok(()) } - - let context = Arc::new( - ClientContext::new(ClientConfig { - network: NetworkConfig { - endpoints: Some(get_server_endpoints(config)), - access_key: config.access_key.clone(), - ..Default::default() - }, - ..Default::default() - }).map_err(|e| format!("Failed to create ctx: {}", e))?, - ); + let context = get_network_context(config) + .map_err(|e| format!("Failed to create ctx: {}", e))?; let filter = if let Some(lt_bound) = lt_bound { let lt_bound = format!("0x{:x}", lt_bound); @@ -481,16 +474,7 @@ pub async fn replay( } pub async fn fetch_block(config: &Config, block_id: &str, filename: &str) -> Result<(), failure::Error> { - let context = Arc::new( - ClientContext::new(ClientConfig { - network: NetworkConfig { - endpoints: Some(get_server_endpoints(config)), - access_key: config.access_key.clone(), - ..Default::default() - }, - ..Default::default() - })? - ); + let context = get_network_context(config)?; let block = query_collection( context.clone(), From 8881f311419f93ce3ee03e0ffc62ea5dc77d1c90 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Wed, 5 Oct 2022 20:42:29 +0400 Subject: [PATCH 09/12] Fixed help message --- src/main.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 01b91885..edd3612c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -511,7 +511,7 @@ async fn main_internal() -> Result <(), String> { .arg(Arg::with_name("ENDPOINTS") .required(true) .takes_value(true) - .help("List of endpoints."))) + .help("List of endpoints (comma separated)."))) .subcommand(SubCommand::with_name("remove") .about("Remove endpoints list.") .arg(url_arg.clone())) From cf516cc515bf41ddb9b326e65af88c24bce26050 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Thu, 6 Oct 2022 14:20:04 +0400 Subject: [PATCH 10/12] Fixed endpoints cnt for local network --- src/config.rs | 2 +- src/helpers.rs | 13 +++++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/config.rs b/src/config.rs index bd62df2e..eb77b04b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -20,7 +20,7 @@ use crate::helpers::default_config_name; const TESTNET: &str = "net.evercloud.dev"; const MAINNET: &str = "main.evercloud.dev"; -const LOCALNET: &str = "http://127.0.0.1/"; +pub const LOCALNET: &str = "http://127.0.0.1/"; fn default_url() -> String { TESTNET.to_string() diff --git a/src/helpers.rs b/src/helpers.rs index 2daa09a7..7984bf03 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -12,7 +12,7 @@ */ use std::env; use std::path::PathBuf; -use crate::config::Config; +use crate::config::{Config, LOCALNET}; use std::sync::Arc; use std::time::{Duration, SystemTime}; @@ -31,7 +31,7 @@ use serde_json::Value; use ton_client::abi::Abi::Contract; use url::Url; use crate::call::parse_params; -use crate::FullConfig; +use crate::{FullConfig, resolve_net_name}; pub const TEST_MAX_LEVEL: log::LevelFilter = log::LevelFilter::Debug; pub const MAX_LEVEL: log::LevelFilter = log::LevelFilter::Warn; @@ -160,6 +160,11 @@ pub fn create_client(config: &Config) -> Result { println!("Connecting to:\n\tUrl: {}", config.url); println!("\tEndpoints: {:?}\n", modified_endpoints); } + let endpoints_cnt = if resolve_net_name(&config.url).unwrap_or(config.url.clone()).eq(LOCALNET) { + 1_u8 + } else { + modified_endpoints.len() as u8 + }; let cli_conf = ClientConfig { abi: AbiConfig { workchain: config.wc, @@ -171,9 +176,9 @@ pub fn create_client(config: &Config) -> Result { mnemonic_word_count: WORD_COUNT, hdkey_derivation_path: HD_PATH.to_string(), }, - network: ton_client::net::NetworkConfig { + network: NetworkConfig { server_address: Some(config.url.to_owned()), - sending_endpoint_count: modified_endpoints.len() as u8, + sending_endpoint_count: endpoints_cnt, endpoints: if modified_endpoints.is_empty() { None } else { From 9ef96d0cb7ff143d1449064da4467df23369fc6d Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Thu, 6 Oct 2022 14:42:15 +0400 Subject: [PATCH 11/12] Increased version --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6627bb85..d30cf39c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "tonos-cli" -version = "0.28.17" +version = "0.28.18" dependencies = [ "assert_cmd", "async-trait", diff --git a/Cargo.toml b/Cargo.toml index a01596e2..338d2b53 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ license = 'Apache-2.0' name = 'tonos-cli' readme = 'README.md' repository = 'https://github.com/tonlabs/tonos-cli' -version = '0.28.17' +version = '0.28.18' [dependencies] async-trait = '0.1.42' From 6b8afcfa7a63e386576d9e464ae166c754a92fb9 Mon Sep 17 00:00:00 2001 From: SilkovAlexander Date: Thu, 6 Oct 2022 17:34:29 +0400 Subject: [PATCH 12/12] Fixed fro situation when only url set without endpoints --- src/helpers.rs | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/helpers.rs b/src/helpers.rs index 7984bf03..e39d58fd 100644 --- a/src/helpers.rs +++ b/src/helpers.rs @@ -121,22 +121,18 @@ pub fn create_client_local() -> Result { } pub fn get_server_endpoints(config: &Config) -> Vec { - if config.project_id.is_some() { - let mut cur_endpoints = match config.endpoints.len() { - 0 => vec![config.url.clone()], - _ => config.endpoints.clone(), - }; - cur_endpoints.iter_mut().map(|end| { + let mut cur_endpoints = match config.endpoints.len() { + 0 => vec![config.url.clone()], + _ => config.endpoints.clone(), + }; + cur_endpoints.iter_mut().map(|end| { let mut end = end.trim_end_matches('/').to_owned(); + if config.project_id.is_some() { end.push_str("/"); end.push_str(&config.project_id.clone().unwrap()); - end.to_owned() - }).collect::>() - } else { - config.endpoints.clone().iter_mut().map(|end| { - end.trim_end_matches('/').to_owned() - }).collect::>() - } + } + end.to_owned() + }).collect::>() } pub fn get_network_context(config: &Config) -> Result, failure::Error> {