Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions src/api/controllers/authorization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::sync::Arc;

use aide::{OperationInput, OperationOutput};
use axum::body::Body;
use axum::extract::{FromRequest, FromRequestParts, OriginalUri};
use axum::extract::{FromRequestParts, OriginalUri};
use axum::http::request::Parts;
use axum::http::Request;
use axum::http::{Method, StatusCode};
Expand Down Expand Up @@ -95,9 +95,7 @@ async fn check_api_key(
// Forward service id to request handler
req.extensions_mut().insert(IdExtractor(service_id));

Ok(Request::from_request(req, &auth_service)
.await
.expect("can't fail"))
Ok(req)
}

#[derive(Debug, Clone)]
Expand Down
2 changes: 1 addition & 1 deletion src/api/controllers/misc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ pub async fn post_prepare_generic_message(
)
.await?;

let message_hash = ctx.memory_storage.add_message(unsigned_message);
let message_hash = ctx.memory_storage.add_message(unsigned_message)?;

let elapsed = start.elapsed();
histogram!("execution_time_seconds", "method" => "prepareGenericMessage").record(elapsed);
Expand Down
2 changes: 1 addition & 1 deletion src/api/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ impl Api {
))
.fallback(controllers::handler_404);

let listener = tokio::net::TcpListener::bind(server_addr).await.unwrap();
let listener = tokio::net::TcpListener::bind(server_addr).await?;

let serve = axum::serve(listener, app);

Expand Down
15 changes: 4 additions & 11 deletions src/api/requests/transactions.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use bigdecimal::BigDecimal;
use derive_more::Constructor;
use num_traits::FromPrimitive;

use schemars::JsonSchema;
use serde::Deserialize;
Expand Down Expand Up @@ -125,9 +124,7 @@ impl From<TonTokenTransactionSendRequest> for TokenTransactionSend {
send_gas_to: c.send_gas_to,
value: c.value,
notify_receiver: c.notify_receiver.unwrap_or(false),
fee: c
.fee
.unwrap_or_else(|| BigDecimal::from_u64(TOKEN_FEE).unwrap()),
fee: c.fee.unwrap_or_else(|| BigDecimal::from(TOKEN_FEE)),
payload: c.payload,
}
}
Expand All @@ -154,9 +151,7 @@ impl From<TonTokenTransactionBurnRequest> for TokenTransactionBurn {
send_gas_to: c.send_gas_to,
callback_to: c.callback_to,
value: c.value,
fee: c
.fee
.unwrap_or_else(|| BigDecimal::from_u64(TOKEN_FEE).unwrap()),
fee: c.fee.unwrap_or_else(|| BigDecimal::from(TOKEN_FEE)),
}
}
}
Expand Down Expand Up @@ -187,10 +182,8 @@ impl From<TonTokenTransactionMintRequest> for TokenTransactionMint {
notify: c.notify.unwrap_or(false),
deploy_wallet_value: c
.deploy_wallet_value
.unwrap_or_else(|| BigDecimal::from_u64(DEPLOY_TOKEN_VALUE).unwrap()),
fee: c
.fee
.unwrap_or_else(|| BigDecimal::from_u64(TOKEN_FEE).unwrap()),
.unwrap_or_else(|| BigDecimal::from(DEPLOY_TOKEN_VALUE)),
fee: c.fee.unwrap_or_else(|| BigDecimal::from(TOKEN_FEE)),
}
}
}
4 changes: 2 additions & 2 deletions src/client/callback/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub struct CallbackClient {
impl CallbackClient {
pub fn new() -> Self {
Self {
client: reqwest::ClientBuilder::new().build().unwrap(),
client: reqwest::Client::new(),
}
}
}
Expand Down Expand Up @@ -62,7 +62,7 @@ impl CallbackClient {
}

fn calc_sign(body: String, url: String, timestamp_ms: i64, secret: String) -> String {
let concat = format!("{}{}{}", timestamp_ms, url, body);
let concat = format!("{timestamp_ms}{url}{body}");
let calculated_signature = hmac_sha256::HMAC::mac(concat.as_bytes(), secret.as_bytes());
general_purpose::STANDARD.encode(calculated_signature)
}
17 changes: 6 additions & 11 deletions src/client/ton/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,9 @@ impl TonClient {
.await?
.into_iter()
.map(|item| {
StdAddr::from_str(&format!("{}:{}", item.workchain_id, item.hex))
.map_err(From::from)
let workchain_id = item.workchain_id;
let hex = item.hex;
StdAddr::from_str(&format!("{workchain_id}:{hex}")).map_err(From::from)
})
.collect::<anyhow::Result<Vec<StdAddr>>>()?;

Expand Down Expand Up @@ -865,19 +866,15 @@ impl TonClient {
pub async fn get_blockchain_info(&self) -> Result<BlockchainInfo, Error> {
let gen_utime = self.ton_core.current_utime();

let network_id = match () {
_ => TYCHO_TESTNET_CHAIN_ID,
};

let subscriber_metrics = self.ton_core.context.ton_subscriber.metrics();

Ok(BlockchainInfo {
network_id,
network_id: subscriber_metrics.network_id,
synced: subscriber_metrics.ready,
subscriber_pending_messages: subscriber_metrics.pending_message_count,
tip_block_ts: gen_utime,
masterchain_height: 0,
masterchain_last_updated: 0,
masterchain_height: subscriber_metrics.mc_seqno,
masterchain_last_updated: subscriber_metrics.masterchain_last_updated,
})
}

Expand Down Expand Up @@ -1266,8 +1263,6 @@ fn build_token_transaction(
})
}

const TYCHO_TESTNET_CHAIN_ID: i32 = -4000;

#[derive(Debug)]
pub struct PrepareResult {
pub sent_transaction: SentTransaction,
Expand Down
17 changes: 12 additions & 5 deletions src/cmd/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,14 @@ impl Cmd {
cli::logger::init_logger(&node_config.logger_config, self.logger_config.clone())?;
cli::logger::set_abort_with_tracing();

node_config.threads.init_reclaimer().unwrap();
node_config.threads.init_global_rayon_pool().unwrap();
node_config
.threads
.init_reclaimer()
.context("failed to initialize memory reclaimer")?;
node_config
.threads
.init_global_rayon_pool()
.context("failed to initialize global rayon pool")?;
node_config
.threads
.build_tokio_runtime()?
Expand All @@ -115,9 +121,10 @@ impl Cmd {
}

// Build node.
let keys = NodeKeys::load_or_create(self.keys.unwrap())?;
let global_config = GlobalConfig::from_file(self.global_config.unwrap())
.context("failed to load global config")?;
let keys = NodeKeys::load_or_create(self.keys.context("no keys path")?)?;
let global_config =
GlobalConfig::from_file(self.global_config.context("no global config path")?)
.context("failed to load global config")?;
let public_ip = cli::resolve_public_ip(node_config.base.public_ip).await?;
let public_addr = SocketAddr::new(public_ip, node_config.base.port);

Expand Down
1 change: 1 addition & 0 deletions src/models/account_enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ impl From<AddressDb> for Account {
fn from(a: AddressDb) -> Self {
let account = StdAddr::from_str(&format!("{}:{}", a.workchain_id, a.hex)).unwrap();
let base64url = Address(account.display_base64_url(true).to_string());

Self {
workchain_id: a.workchain_id,
hex: Address(a.hex),
Expand Down
91 changes: 62 additions & 29 deletions src/models/owners_cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,16 +32,9 @@ impl OwnersCache {
.get_token_owner_by_address(address.to_string())
.await
.ok()?;
OwnerInfo {
owner_address: StdAddr::from_str(&format!(
"{}:{}",
got.owner_account_workchain_id, got.owner_account_hex
))
.unwrap(),
root_address: StdAddr::from_str(&got.root_address).unwrap(),
code_hash: HashBytes::from_slice(&got.code_hash),
version: got.version.into(),
}
let (_, got) = parse_owner_cache_entry(got)?;
self.cache.lock().put(address.clone(), got.clone());
got
}
};
Some(info)
Expand Down Expand Up @@ -77,28 +70,68 @@ impl OwnersCache {
pub async fn new(sqlx_client: SqlxClient) -> Result<Self, anyhow::Error> {
let balances = sqlx_client.get_all_token_owners().await?;
// no more than 10 mb
let mut cache = LruCache::new(NonZeroUsize::new(5000).unwrap());
balances.into_iter().for_each(|x| {
let k = StdAddr::from_str(&x.address).unwrap();
let owner_address = StdAddr::from_str(&format!(
"{}:{}",
x.owner_account_workchain_id, x.owner_account_hex
))
.unwrap();
let root_address = StdAddr::from_str(&x.root_address).unwrap();
cache.put(
k,
OwnerInfo {
owner_address,
root_address,
code_hash: HashBytes::from_slice(&x.code_hash),
version: x.version.into(),
},
);
});
let capacity = NonZeroUsize::new(5000)
.ok_or_else(|| anyhow::anyhow!("owners cache capacity must be non-zero"))?;
let mut cache = LruCache::new(capacity);
balances
.into_iter()
.filter_map(parse_owner_cache_entry)
.for_each(|(key, value)| {
cache.put(key, value);
});
Ok(Self {
cache: Arc::new(Mutex::new(cache)),
db: sqlx_client,
})
}
}

fn parse_owner_cache_entry(row: TokenOwnerFromDb) -> Option<(StdAddr, OwnerInfo)> {
let key = parse_std_address(&row.address, "address", &row.address)?;
let workchain_id = row.owner_account_workchain_id;
let hex = &row.owner_account_hex;
let owner = format!("{workchain_id}:{hex}");
let owner_address = parse_std_address(&owner, "owner_address", &row.address)?;
let root_address = parse_std_address(&row.root_address, "root_address", &row.address)?;
let code_hash = parse_code_hash(&row.code_hash, &row.address)?;

Some((
key,
OwnerInfo {
owner_address,
root_address,
code_hash,
version: row.version.into(),
},
))
}

fn parse_std_address(address: &str, field: &'static str, row_address: &str) -> Option<StdAddr> {
StdAddr::from_str(address)
.map_err(|error| {
tracing::error!(
row_address,
field,
address,
?error,
"failed to parse owner cache address"
);
})
.ok()
}

fn parse_code_hash(code_hash: &[u8], row_address: &str) -> Option<HashBytes> {
let code_hash: [u8; 32] = code_hash
.try_into()
.map_err(|error| {
tracing::error!(
row_address,
len = code_hash.len(),
?error,
"failed to parse owner cache code hash"
);
})
.ok()?;

Some(HashBytes::from(code_hash))
}
2 changes: 1 addition & 1 deletion src/models/service_id.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,6 @@ impl FromStr for ServiceId {

impl Display for ServiceId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str(&format!("{}", self.0))
Display::fmt(&self.0, f)
}
}
33 changes: 24 additions & 9 deletions src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,10 @@ impl EngineContext {
.max_connections(config.db_pool_size)
.connect(&config.database_url)
.await
.unwrap_or_else(|_| {
panic!(
"Failed connection to database url - {}",
config.database_url
)
});
.with_context(|| {
let database_url = &config.database_url;
format!("failed connection to database url - {database_url}")
})?;

sqlx::migrate!().run(&pool).await?;

Expand Down Expand Up @@ -282,6 +280,20 @@ impl EngineContext {
}
}
}

async fn persist_last_key_block_state(&self, cx: &StateSubscriberContext) -> Result<()> {
let block_id = cx.state.block_id();
if !cx.mc_is_key_block || block_id.is_masterchain() {
return Ok(());
}

self.ton_core
.context
.sqlx_client
.create_last_key_block(&block_id.to_string())
.await
.context("failed to persist last key block state")
}
}

pub type ShutdownRequestsRx = mpsc::UnboundedReceiver<()>;
Expand All @@ -291,11 +303,14 @@ impl StateSubscriber for EngineContext {
type HandleStateFut<'a> = BoxFuture<'a, Result<()>>;

fn handle_state<'a>(&'a self, cx: &'a StateSubscriberContext) -> Self::HandleStateFut<'a> {
Box::pin(
Box::pin(async move {
self.ton_core
.context
.ton_subscriber
.process_block(&cx.block, &cx.state),
)
.process_block(&cx.block, &cx.state)
.await?;

self.persist_last_key_block_state(cx).await
})
}
}
9 changes: 4 additions & 5 deletions src/services/auth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ impl AuthService {
let key = self
.get_key(api_key)
.await
.map_err(|_| anyhow::Error::msg(format!("Can not find api key {} in db", api_key)))?;
.map_err(|_| anyhow::Error::msg(format!("Can not find api key {api_key} in db")))?;

if let Some(whitelist) = key.whitelist {
let whitelist: Vec<String> = serde_json::from_value(whitelist)
Expand All @@ -49,7 +49,7 @@ impl AuthService {
real_ip.ok_or_else(|| anyhow::Error::msg("Failed to read x-real-ip header"))?;

if !whitelist.contains(&real_ip) {
anyhow::bail!(format!("Ip {} is not in whitelist.", real_ip))
anyhow::bail!(format!("Ip {real_ip} is not in whitelist."))
}
}

Expand All @@ -67,12 +67,11 @@ impl AuthService {
let delta = (now - then).num_seconds();
if delta > TIMESTAMP_EXPIRED_SEC {
anyhow::bail!(format!(
"TIMESTAMP expired. server time: {}, header time: {}",
now, then
"TIMESTAMP expired. server time: {now}, header time: {then}"
))
}

let concat = format!("{}{}{}", timestamp_ms, path, body);
let concat = format!("{timestamp_ms}{path}{body}");

let calculated_signature = hmac_sha256::HMAC::mac(concat.as_bytes(), key.secret.as_bytes());

Expand Down
Loading