Skip to content

Commit

Permalink
Merge pull request #236 from tonlabs/SilkovAlexander/fix_retry
Browse files Browse the repository at this point in the history
Fixed retry as in SDK
  • Loading branch information
SilkovAlexander authored Aug 20, 2021
2 parents b362f37 + f3320d4 commit 611e1fd
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 25 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ readme = "README.md"
license = "Apache-2.0"
keywords = ["TON", "SDK", "smart contract", "tonlabs", "solidity"]
edition = "2018"
version = "0.17.17"
version = "0.17.18"

[dependencies]
async-trait = "0.1.42"
Expand Down
37 changes: 13 additions & 24 deletions src/call.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ use ton_client::processing::{
ParamsOfWaitForTransaction,
wait_for_transaction,
send_message,
ErrorCode
};
use ton_client::tvm::{run_tvm, run_get, ParamsOfRunTvm, ParamsOfRunGet, run_executor, ParamsOfRunExecutor, AccountForExecutor};
use ton_client::tvm::{run_tvm, run_get, ParamsOfRunTvm, ParamsOfRunGet, run_executor, ParamsOfRunExecutor, AccountForExecutor, StdContractError};
use ton_client::error::ClientError;
use ton_block::{Account, Serializable, Deserializable};
use std::str::FromStr;
Expand Down Expand Up @@ -470,10 +471,10 @@ pub async fn call_contract_with_result(

let mut attempts = conf.retries + 1; // + 1 (first try)
let total_attempts = attempts.clone();
let expire_at = conf.lifetime + now();
let time = now_ms();
while attempts != 0 {
attempts -= 1;
let expire_at = conf.lifetime + now();
let time = now_ms();
let header = FunctionHeader {
expire: Some(expire_at),
time: Some(time),
Expand All @@ -494,30 +495,18 @@ pub async fn call_contract_with_result(
print_encoded_message(&msg);
}

let mut retry: bool = true;
let mut retry: bool = false;
let error_handler = |err: ClientError| {
// obtaining error code
let code = err.code.clone();
// but if it was simulated locally and local exit code is not zero,
// we ignore previous exit code because it means we shouldn't make a retry.
if !err.data["exit_code"].is_null() {
if err.data["exit_code"].as_i64().unwrap_or(-1) != 0 {
retry = false;
// retry only if error code is MessageExpired
if err.code == ErrorCode::MessageExpired as u32{
// but we should also check possible local execution error
let local_error = err.data["local_error"]["data"]["exit_code"].clone();
if err.data["local_error"].is_null() ||
local_error.as_i64().unwrap_or(-1) == StdContractError::ReplayProtection as i64||
local_error.as_i64().unwrap_or(-1) == StdContractError::ExtMessageExpired as i64 {
retry = true;
}
}
// There is also another way how SDK can print local run results.
let local_error = err.data["local_error"]["data"]["exit_code"].clone();
if !local_error.is_null() {
if local_error.as_i64().unwrap_or(-1) != 0 {
retry = false;
}
}
// if error code was 4XX then don't perform a retry. Also if error was 508,
// it means that message could have been delivered after timeout and for not
// to cause double call we shouldn't perform a retry.
if (((code / 100) as u32 % 10) == 4) || (code == 508) {
retry = false;
}
};

if (!local && conf.local_run) || is_fee {
Expand Down

0 comments on commit 611e1fd

Please sign in to comment.