From 5ec928993a7122a3dc3bdfa454767f9a7b36f3ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 23 Aug 2024 13:03:07 +0100 Subject: [PATCH 1/2] refactor tendermint to only re-export v0.37 --- crates/apps/src/bin/namada-client/main.rs | 2 +- crates/apps_lib/src/cli.rs | 4 +-- crates/apps_lib/src/cli/api.rs | 4 +-- crates/apps_lib/src/client/rpc.rs | 2 +- crates/apps_lib/src/client/tx.rs | 2 +- crates/apps_lib/src/client/utils.rs | 2 +- crates/apps_lib/src/config/genesis/chain.rs | 8 +++--- crates/apps_lib/src/config/mod.rs | 6 ++-- crates/apps_lib/src/config/utils.rs | 2 +- crates/apps_lib/src/lib.rs | 8 ++---- crates/apps_lib/src/tendermint_node.rs | 4 +-- crates/core/src/lib.rs | 20 +++++++++++-- crates/events/src/extend.rs | 4 +-- crates/events/src/lib.rs | 6 ++-- crates/ibc/src/event.rs | 2 +- crates/node/src/bench_utils.rs | 7 ++--- crates/node/src/broadcaster.rs | 4 +-- crates/node/src/lib.rs | 17 ++++++----- crates/node/src/shell/block_alloc.rs | 4 +-- crates/node/src/shell/finalize_block.rs | 15 ++++------ crates/node/src/shell/init_chain.rs | 28 ++++++++----------- crates/node/src/shell/mod.rs | 16 +++++------ crates/node/src/shell/prepare_proposal.rs | 17 ++++++----- crates/node/src/shell/process_proposal.rs | 2 +- crates/node/src/shell/snapshots.rs | 9 +++--- crates/node/src/shell/testing/client.rs | 2 +- crates/node/src/shell/testing/node.rs | 15 +++++----- .../shell/vote_extensions/bridge_pool_vext.rs | 19 +++++++------ .../src/shell/vote_extensions/eth_events.rs | 19 +++++++------ .../shell/vote_extensions/val_set_update.rs | 19 +++++++------ crates/node/src/shims/abcipp_shim.rs | 8 ++---- crates/node/src/shims/abcipp_shim_types.rs | 20 ++++++------- crates/node/src/tendermint_node.rs | 8 ++---- crates/node/src/utils.rs | 2 +- crates/sdk/src/queries/types.rs | 2 +- crates/tests/src/e2e/ibc_tests.rs | 6 ++-- crates/tests/src/e2e/ledger_tests.rs | 2 +- crates/tests/src/integration/ledger_tests.rs | 6 ++-- crates/tests/src/integration/setup.rs | 18 ++++++------ fuzz/fuzz_targets/txs_prepare_proposal.rs | 2 +- 40 files changed, 171 insertions(+), 172 deletions(-) diff --git a/crates/apps/src/bin/namada-client/main.rs b/crates/apps/src/bin/namada-client/main.rs index 666f7d39b5..32fd2d717b 100644 --- a/crates/apps/src/bin/namada-client/main.rs +++ b/crates/apps/src/bin/namada-client/main.rs @@ -1,6 +1,6 @@ use color_eyre::eyre::Result; use namada_apps_lib::cli::api::{CliApi, CliIo}; -use namada_apps_lib::facade::tendermint_rpc::HttpClient; +use namada_apps_lib::tendermint_rpc::HttpClient; use namada_apps_lib::{cli, logging}; use tracing_subscriber::filter::LevelFilter; diff --git a/crates/apps_lib/src/cli.rs b/crates/apps_lib/src/cli.rs index 51eacc4cc3..c1b4c68534 100644 --- a/crates/apps_lib/src/cli.rs +++ b/crates/apps_lib/src/cli.rs @@ -3190,8 +3190,8 @@ pub mod args { use crate::client::utils::PRE_GENESIS_DIR; use crate::config::genesis::AddrOrPk; use crate::config::{self, Action, ActionAtHeight}; - use crate::facade::tendermint::Timeout; - use crate::facade::tendermint_rpc::Url; + use crate::tendermint::Timeout; + use crate::tendermint_rpc::Url; use crate::wrap; pub const ADDRESS: Arg = arg("address"); diff --git a/crates/apps_lib/src/cli/api.rs b/crates/apps_lib/src/cli/api.rs index a955af6644..efe19e0a62 100644 --- a/crates/apps_lib/src/cli/api.rs +++ b/crates/apps_lib/src/cli/api.rs @@ -3,8 +3,8 @@ use namada_sdk::io::Io; use namada_sdk::queries::Client; use namada_sdk::rpc::wait_until_node_is_synched; -use crate::facade::tendermint_rpc::client::CompatMode; -use crate::facade::tendermint_rpc::{HttpClient, Url as TendermintUrl}; +use crate::tendermint_rpc::client::CompatMode; +use crate::tendermint_rpc::{HttpClient, Url as TendermintUrl}; /// Trait for clients that can be used with the CLI. #[async_trait::async_trait(?Send)] diff --git a/crates/apps_lib/src/client/rpc.rs b/crates/apps_lib/src/client/rpc.rs index 9bb20e99c8..ec48adc9ba 100644 --- a/crates/apps_lib/src/client/rpc.rs +++ b/crates/apps_lib/src/client/rpc.rs @@ -49,7 +49,7 @@ use namada_sdk::{ }; use crate::cli::{self, args}; -use crate::facade::tendermint::merkle::proof::ProofOps; +use crate::tendermint::merkle::proof::ProofOps; /// Query the status of a given transaction. /// diff --git a/crates/apps_lib/src/client/tx.rs b/crates/apps_lib/src/client/tx.rs index 46e13e71f0..211f347942 100644 --- a/crates/apps_lib/src/client/tx.rs +++ b/crates/apps_lib/src/client/tx.rs @@ -28,8 +28,8 @@ use crate::cli::{args, safe_exit}; use crate::client::tx::signing::{default_sign, SigningTxData}; use crate::client::tx::tx::ProcessTxResponse; use crate::config::TendermintMode; -use crate::facade::tendermint_rpc::endpoint::broadcast::tx_sync::Response; use crate::tendermint_node; +use crate::tendermint_rpc::endpoint::broadcast::tx_sync::Response; use crate::wallet::{ gen_validator_keys, read_and_confirm_encryption_password, WalletTransport, }; diff --git a/crates/apps_lib/src/client/utils.rs b/crates/apps_lib/src/client/utils.rs index a43533afcf..53826e30f0 100644 --- a/crates/apps_lib/src/client/utils.rs +++ b/crates/apps_lib/src/client/utils.rs @@ -33,7 +33,7 @@ use crate::config::genesis::transactions::{ use crate::config::genesis::{AddrOrPk, GenesisAddress}; use crate::config::global::GlobalConfig; use crate::config::{self, genesis, get_default_namada_folder, TendermintMode}; -use crate::facade::tendermint::node::Id as TendermintNodeId; +use crate::tendermint::node::Id as TendermintNodeId; use crate::wallet::{pre_genesis, CliWalletUtils}; use crate::{tendermint_node, wasm_loader}; diff --git a/crates/apps_lib/src/config/genesis/chain.rs b/crates/apps_lib/src/config/genesis/chain.rs index df50cb07b5..ac4ad408c4 100644 --- a/crates/apps_lib/src/config/genesis/chain.rs +++ b/crates/apps_lib/src/config/genesis/chain.rs @@ -29,8 +29,8 @@ use super::{templates, transactions}; use crate::config::genesis::templates::Validated; use crate::config::utils::{set_ip, set_port}; use crate::config::{Config, TendermintMode}; -use crate::facade::tendermint::node::Id as TendermintNodeId; -use crate::facade::tendermint_config::net::Address as TendermintAddress; +use crate::tendermint::node::Id as TendermintNodeId; +use crate::tendermint_config::net::Address as TendermintAddress; use crate::tendermint_node::id_from_pk; use crate::wallet::{Alias, CliWalletUtils}; use crate::wasm_loader; @@ -497,7 +497,7 @@ pub fn finalize( templates: templates::All, chain_id_prefix: ChainIdPrefix, genesis_time: DateTimeUtc, - consensus_timeout_commit: crate::facade::tendermint::Timeout, + consensus_timeout_commit: crate::tendermint::Timeout, ) -> Finalized { let genesis_time: Rfc3339String = genesis_time.into(); let consensus_timeout_commit: DurationNanos = @@ -883,7 +883,7 @@ mod test { let genesis_time = DateTimeUtc::from_str(GENESIS_TIME).unwrap(); let consensus_timeout_commit = - crate::facade::tendermint::Timeout::from_str("1s").unwrap(); + crate::tendermint::Timeout::from_str("1s").unwrap(); let finalized_0 = finalize( templates.clone(), diff --git a/crates/apps_lib/src/config/mod.rs b/crates/apps_lib/src/config/mod.rs index 9f73b6c48a..b60b0f494f 100644 --- a/crates/apps_lib/src/config/mod.rs +++ b/crates/apps_lib/src/config/mod.rs @@ -18,9 +18,7 @@ use serde::{Deserialize, Serialize}; use thiserror::Error; use crate::cli; -use crate::facade::tendermint_config::{ - TendermintConfig, TxIndexConfig, TxIndexer, -}; +use crate::tendermint_config::{TendermintConfig, TxIndexConfig, TxIndexer}; /// Base directory contains global config and chain directories. pub const DEFAULT_BASE_DIR: &str = ".namada"; @@ -857,7 +855,7 @@ namespace = "cometbft" #[cfg(test)] mod tests { use super::DEFAULT_COMETBFT_CONFIG; - use crate::facade::tendermint_config::TendermintConfig; + use crate::tendermint_config::TendermintConfig; #[test] fn test_default_cometbft_config() { diff --git a/crates/apps_lib/src/config/utils.rs b/crates/apps_lib/src/config/utils.rs index 41658a000c..dbfebf3b3f 100644 --- a/crates/apps_lib/src/config/utils.rs +++ b/crates/apps_lib/src/config/utils.rs @@ -7,7 +7,7 @@ use std::{cmp, env}; use itertools::Either; use crate::cli; -use crate::facade::tendermint_config::net::Address as TendermintAddress; +use crate::tendermint_config::net::Address as TendermintAddress; /// Find how many threads to use from an environment variable if it's set and /// valid (>= 1). If the environment variable is invalid, exits the process with diff --git a/crates/apps_lib/src/lib.rs b/crates/apps_lib/src/lib.rs index 12a7f7991e..3ae8f0a36f 100644 --- a/crates/apps_lib/src/lib.rs +++ b/crates/apps_lib/src/lib.rs @@ -22,10 +22,6 @@ pub mod tendermint_node; pub mod wallet; pub mod wasm_loader; +pub use namada_core::{tendermint, tendermint_proto}; pub use namada_sdk::*; - -pub mod facade { - // TODO(namada#3248): only re-export v037 `tendermint-rs` - pub use namada_core::{tendermint, tendermint_proto}; - pub use {tendermint_config, tendermint_rpc}; -} +pub use {tendermint_config, tendermint_rpc}; diff --git a/crates/apps_lib/src/tendermint_node.rs b/crates/apps_lib/src/tendermint_node.rs index 1fc100e027..3c2197915a 100644 --- a/crates/apps_lib/src/tendermint_node.rs +++ b/crates/apps_lib/src/tendermint_node.rs @@ -6,8 +6,8 @@ use serde_json::json; use sha2::{Digest, Sha256}; use thiserror::Error; -use crate::facade::tendermint::node::Id as TendermintNodeId; -use crate::facade::tendermint_config::Error as TendermintError; +use crate::tendermint::node::Id as TendermintNodeId; +use crate::tendermint_config::Error as TendermintError; /// Env. var to output Tendermint log to stdout pub const ENV_VAR_TM_STDOUT: &str = "NAMADA_CMT_STDOUT"; diff --git a/crates/core/src/lib.rs b/crates/core/src/lib.rs index 377d30737d..bf94f26e4f 100644 --- a/crates/core/src/lib.rs +++ b/crates/core/src/lib.rs @@ -23,8 +23,24 @@ pub mod bytes; pub mod control_flow; pub mod hints; -// TODO(namada#3248): only re-export v037 `tendermint-rs` -pub use {masp_primitives, tendermint, tendermint_proto}; +pub use masp_primitives; +/// Re-export of tendermint v0.37 +pub mod tendermint { + /// Re-export of tendermint v0.37 ABCI + pub mod abci { + pub use tendermint::abci::response::ApplySnapshotChunkResult; + pub use tendermint::abci::{ + types, Code, Event, EventAttribute, MethodKind, + }; + pub use tendermint::v0_37::abci::*; + } + pub use tendermint::*; +} +/// Re-export of tendermint-proto v0.37 +pub mod tendermint_proto { + pub use tendermint_proto::google; // 💩 + pub use tendermint_proto::v0_37::*; +} /// Borsh binary encoding (re-exported) from official crate with custom ext. pub mod borsh { pub use borsh::*; diff --git a/crates/events/src/extend.rs b/crates/events/src/extend.rs index ae68e66470..8f3fdcbbb7 100644 --- a/crates/events/src/extend.rs +++ b/crates/events/src/extend.rs @@ -142,7 +142,7 @@ impl AttributesMap for Vec { } impl AttributesMap - for Vec + for Vec { #[inline] fn insert_attribute(&mut self, key: K, value: V) @@ -150,7 +150,7 @@ impl AttributesMap K: Into, V: Into, { - self.push(namada_core::tendermint_proto::v0_37::abci::EventAttribute { + self.push(namada_core::tendermint_proto::abci::EventAttribute { key: key.into(), value: value.into(), index: true, diff --git a/crates/events/src/lib.rs b/crates/events/src/lib.rs index 71e0df8ff5..45e20c43f0 100644 --- a/crates/events/src/lib.rs +++ b/crates/events/src/lib.rs @@ -466,7 +466,7 @@ impl Event { } } -impl From for namada_core::tendermint_proto::v0_37::abci::Event { +impl From for namada_core::tendermint_proto::abci::Event { fn from(event: Event) -> Self { Self { r#type: { @@ -485,14 +485,14 @@ impl From for namada_core::tendermint_proto::v0_37::abci::Event { .attributes .into_iter() .map(|(key, value)| { - namada_core::tendermint_proto::v0_37::abci::EventAttribute { + namada_core::tendermint_proto::abci::EventAttribute { key, value, index: true, } }) .chain(std::iter::once_with(|| { - namada_core::tendermint_proto::v0_37::abci::EventAttribute { + namada_core::tendermint_proto::abci::EventAttribute { key: "event-level".to_string(), value: event.level.to_string(), index: true, diff --git a/crates/ibc/src/event.rs b/crates/ibc/src/event.rs index 5d340aee25..51c81fe2b7 100644 --- a/crates/ibc/src/event.rs +++ b/crates/ibc/src/event.rs @@ -431,7 +431,7 @@ pub fn packet_from_event_attributes( #[cfg(test)] mod tests { use namada_core::hash::Hash; - use namada_core::tendermint_proto::v0_37::abci::Event as AbciEventV037; + use namada_core::tendermint_proto::abci::Event as AbciEventV037; use namada_events::extend::{ ComposeEvent as _, Domain, Height, Log, RawReadFromEventAttributes as _, TxHash, diff --git a/crates/node/src/bench_utils.rs b/crates/node/src/bench_utils.rs index d6b6b8a256..9dc6da077f 100644 --- a/crates/node/src/bench_utils.rs +++ b/crates/node/src/bench_utils.rs @@ -112,11 +112,10 @@ use tempfile::TempDir; use crate::config::global::GlobalConfig; use crate::config::TendermintMode; -use crate::facade::tendermint::v0_37::abci::request::InitChain; -use crate::facade::tendermint_proto::google::protobuf::Timestamp; -use crate::facade::tendermint_rpc; use crate::shell::Shell; -use crate::{config, dry_run_tx}; +use crate::tendermint::abci::request::InitChain; +use crate::tendermint_proto::google::protobuf::Timestamp; +use crate::{config, dry_run_tx, tendermint_rpc}; pub const WASM_DIR: &str = "../../wasm"; diff --git a/crates/node/src/broadcaster.rs b/crates/node/src/broadcaster.rs index 6f0fc652c5..a5d854737d 100644 --- a/crates/node/src/broadcaster.rs +++ b/crates/node/src/broadcaster.rs @@ -5,8 +5,8 @@ use namada_sdk::control_flow::time; use namada_sdk::time::{DateTimeUtc, Utc}; use tokio::sync::mpsc::UnboundedReceiver; -use crate::facade::tendermint_rpc::client::CompatMode; -use crate::facade::tendermint_rpc::{Client, HttpClient}; +use crate::tendermint_rpc::client::CompatMode; +use crate::tendermint_rpc::{Client, HttpClient}; const DEFAULT_BROADCAST_TIMEOUT: u64 = 180; const BROADCASTER_TIMEOUT_ENV_VAR: &str = "NAMADA_BROADCASTER_TIMEOUT_SECS"; diff --git a/crates/node/src/lib.rs b/crates/node/src/lib.rs index 53d20a29b0..bbf5c09cd4 100644 --- a/crates/node/src/lib.rs +++ b/crates/node/src/lib.rs @@ -40,6 +40,9 @@ use namada_apps_lib::config::utils::{ convert_tm_addr_to_socket_addr, num_of_threads, }; use namada_apps_lib::{config, wasm_loader}; +pub use namada_apps_lib::{ + tendermint, tendermint_config, tendermint_proto, tendermint_rpc, +}; use namada_sdk::chain::BlockHeight; use namada_sdk::eth_bridge::ethers::providers::{Http, Provider}; use namada_sdk::migrations::ScheduledMigration; @@ -60,18 +63,14 @@ use self::shims::abcipp_shim::AbciService; use crate::broadcaster::Broadcaster; use crate::config::{ethereum_bridge, TendermintMode}; use crate::ethereum_oracle as oracle; -use crate::facade::tendermint::v0_37::abci::response; -use crate::facade::tower_abci::{split, Server}; use crate::shell::{Error, MempoolTxType, Shell}; use crate::shims::abcipp_shim::AbcippShim; use crate::shims::abcipp_shim_types::shim::{Request, Response}; - -pub mod facade { - pub use namada_apps_lib::facade::*; - pub mod tower_abci { - pub use tower_abci::v037::*; - pub use tower_abci::BoxError; - } +use crate::tendermint::abci::response; +use crate::tower_abci::{split, Server}; +pub mod tower_abci { + pub use tower_abci::v037::*; + pub use tower_abci::BoxError; } /// Env. var to set a number of Tokio RT worker threads diff --git a/crates/node/src/shell/block_alloc.rs b/crates/node/src/shell/block_alloc.rs index ceabd38565..88404bfd49 100644 --- a/crates/node/src/shell/block_alloc.rs +++ b/crates/node/src/shell/block_alloc.rs @@ -44,9 +44,9 @@ use std::marker::PhantomData; use namada_sdk::parameters; use namada_sdk::state::{self, WlState}; -#[allow(unused_imports)] -use crate::facade::tendermint_proto::abci::RequestPrepareProposal; use crate::shell::block_alloc::states::WithNormalTxs; +#[allow(unused_imports)] +use crate::tendermint_proto::abci::RequestPrepareProposal; /// Block allocation failure status responses. #[derive(Debug, Copy, Clone, Eq, PartialEq)] diff --git a/crates/node/src/shell/finalize_block.rs b/crates/node/src/shell/finalize_block.rs index 9bf7e65809..57c52ffac6 100644 --- a/crates/node/src/shell/finalize_block.rs +++ b/crates/node/src/shell/finalize_block.rs @@ -31,10 +31,10 @@ use namada_vote_ext::ethereum_tx_data_variants; use tendermint::abci::types::Misbehavior; use super::*; -use crate::facade::tendermint::abci::types::VoteInfo; -use crate::facade::tendermint_proto; use crate::protocol::{DispatchArgs, DispatchError}; use crate::shell::stats::InternalStats; +use crate::tendermint::abci::types::VoteInfo; +use crate::tendermint_proto; impl Shell where @@ -248,14 +248,11 @@ where // Apply validator set update response.validator_updates = self .get_abci_validator_updates(false, |pk, power| { - let pub_key = tendermint_proto::v0_37::crypto::PublicKey { + let pub_key = tendermint_proto::crypto::PublicKey { sum: Some(key_to_tendermint(&pk).unwrap()), }; let pub_key = Some(pub_key); - tendermint_proto::v0_37::abci::ValidatorUpdate { - pub_key, - power, - } + tendermint_proto::abci::ValidatorUpdate { pub_key, power } }) .expect("Must be able to update validator set"); } @@ -1093,7 +1090,7 @@ fn pos_votes_from_abci( validator, sig_info, }| { - let crate::facade::tendermint::abci::types::Validator { + let crate::tendermint::abci::types::Validator { address, power, } = validator; @@ -1265,12 +1262,12 @@ mod test_finalize_block { use test_log::test; use super::*; - use crate::facade::tendermint::abci::types::Validator; use crate::oracle::control::Command; use crate::shell::test_utils::*; use crate::shims::abcipp_shim_types::shim::request::{ FinalizeBlock, ProcessedTx, }; + use crate::tendermint::abci::types::Validator; const WRAPPER_GAS_LIMIT: u64 = 1_500_000; const STORAGE_VALUE: &str = "test_value"; diff --git a/crates/node/src/shell/init_chain.rs b/crates/node/src/shell/init_chain.rs index c962e7fa39..7f26a5c106 100644 --- a/crates/node/src/shell/init_chain.rs +++ b/crates/node/src/shell/init_chain.rs @@ -27,7 +27,7 @@ use crate::config::genesis::templates::{TokenBalances, TokenConfig}; use crate::config::genesis::transactions::{ BondTx, EstablishedAccountTx, Signed as SignedTx, ValidatorAccountTx, }; -use crate::facade::tendermint_proto::google::protobuf; +use crate::tendermint_proto::google::protobuf; use crate::wasm_loader; /// Errors that represent panics in normal flow but get demoted to errors @@ -100,13 +100,10 @@ where let rsp = response::InitChain { validators: self .get_abci_validator_updates(true, |pk, power| { - let pub_key: crate::facade::tendermint::PublicKey = - pk.into(); + let pub_key: crate::tendermint::PublicKey = pk.into(); let power = - crate::facade::tendermint::vote::Power::try_from( - power, - ) - .unwrap(); + crate::tendermint::vote::Power::try_from(power) + .unwrap(); validator::Update { pub_key, power } }) .expect("Must be able to set genesis validator set"), @@ -194,10 +191,9 @@ where // Set the initial validator set response.validators = self .get_abci_validator_updates(true, |pk, power| { - let pub_key: crate::facade::tendermint::PublicKey = pk.into(); + let pub_key: crate::tendermint::PublicKey = pk.into(); let power = - crate::facade::tendermint::vote::Power::try_from(power) - .unwrap(); + crate::tendermint::vote::Power::try_from(power).unwrap(); validator::Update { pub_key, power } }) .expect("Must be able to set genesis validator set"); @@ -781,13 +777,11 @@ where chain_id: String, genesis: config::genesis::chain::Finalized, ) { - use crate::facade::tendermint::block::Size; - use crate::facade::tendermint::consensus::params::ValidatorParams; - use crate::facade::tendermint::consensus::Params; - use crate::facade::tendermint::evidence::{ - Duration, Params as Evidence, - }; - use crate::facade::tendermint::time::Time; + use crate::tendermint::block::Size; + use crate::tendermint::consensus::params::ValidatorParams; + use crate::tendermint::consensus::Params; + use crate::tendermint::evidence::{Duration, Params as Evidence}; + use crate::tendermint::time::Time; // craft a request to initialize the chain let init = request::InitChain { diff --git a/crates/node/src/shell/mod.rs b/crates/node/src/shell/mod.rs index 2aaa271b51..457129ee56 100644 --- a/crates/node/src/shell/mod.rs +++ b/crates/node/src/shell/mod.rs @@ -75,13 +75,13 @@ use tokio::sync::mpsc::{Receiver, UnboundedSender}; use super::ethereum_oracle::{self as oracle, last_processed_block}; use crate::config::{self, genesis, TendermintMode, ValidatorLocalConfig}; -use crate::facade::tendermint::v0_37::abci::{request, response}; -use crate::facade::tendermint::{self, validator}; -use crate::facade::tendermint_proto::v0_37::crypto::public_key; use crate::protocol::ShellParams; use crate::shims::abcipp_shim_types::shim; use crate::shims::abcipp_shim_types::shim::response::TxResult; use crate::shims::abcipp_shim_types::shim::TakeSnapshot; +use crate::tendermint::abci::{request, response}; +use crate::tendermint::{self, validator}; +use crate::tendermint_proto::crypto::public_key; use crate::{protocol, storage, tendermint_node}; fn key_to_tendermint( @@ -1529,15 +1529,15 @@ pub mod test_utils { use super::*; use crate::config::ethereum_bridge::ledger::ORACLE_CHANNEL_BUFFER_SIZE; - use crate::facade::tendermint::abci::types::Misbehavior; - use crate::facade::tendermint_proto::google::protobuf::Timestamp; - use crate::facade::tendermint_proto::v0_37::abci::{ - RequestPrepareProposal, RequestProcessProposal, - }; use crate::shims::abcipp_shim_types; use crate::shims::abcipp_shim_types::shim::request::{ FinalizeBlock, ProcessedTx, }; + use crate::tendermint::abci::types::Misbehavior; + use crate::tendermint_proto::abci::{ + RequestPrepareProposal, RequestProcessProposal, + }; + use crate::tendermint_proto::google::protobuf::Timestamp; #[derive(Error, Debug)] pub enum TestError { diff --git a/crates/node/src/shell/prepare_proposal.rs b/crates/node/src/shell/prepare_proposal.rs index 27529cfe07..f5271c1115 100644 --- a/crates/node/src/shell/prepare_proposal.rs +++ b/crates/node/src/shell/prepare_proposal.rs @@ -21,11 +21,11 @@ use super::block_alloc::states::{ }; use super::block_alloc::{AllocFailure, BlockAllocator, BlockResources}; use crate::config::ValidatorLocalConfig; -use crate::facade::tendermint_proto::google::protobuf::Timestamp; -use crate::facade::tendermint_proto::v0_37::abci::RequestPrepareProposal; use crate::protocol::{self, ShellParams}; use crate::shell::ShellMode; use crate::shims::abcipp_shim_types::shim::{response, TxBytes}; +use crate::tendermint_proto::abci::RequestPrepareProposal; +use crate::tendermint_proto::google::protobuf::Timestamp; impl Shell where @@ -696,23 +696,22 @@ mod test_prepare_proposal { address: pkh1, power: (u128::try_from(val1.bonded_stake).expect("Test failed") as u64).try_into().unwrap(), }, - sig_info: crate::facade::tendermint::abci::types::BlockSignatureInfo::LegacySigned, + sig_info: crate::tendermint::abci::types::BlockSignatureInfo::LegacySigned, }, VoteInfo { validator: Validator { address: pkh2, power: (u128::try_from(val2.bonded_stake).expect("Test failed") as u64).try_into().unwrap(), }, - sig_info: crate::facade::tendermint::abci::types::BlockSignatureInfo::LegacySigned, + sig_info: crate::tendermint::abci::types::BlockSignatureInfo::LegacySigned, }, ]; let req = FinalizeBlock { proposer_address: pkh1.to_vec(), - decided_last_commit: - crate::facade::tendermint::abci::types::CommitInfo { - round: 0u8.into(), - votes, - }, + decided_last_commit: crate::tendermint::abci::types::CommitInfo { + round: 0u8.into(), + votes, + }, ..Default::default() }; shell.start_new_epoch(Some(req)); diff --git a/crates/node/src/shell/process_proposal.rs b/crates/node/src/shell/process_proposal.rs index e7f5ee9db7..1485b06f15 100644 --- a/crates/node/src/shell/process_proposal.rs +++ b/crates/node/src/shell/process_proposal.rs @@ -9,10 +9,10 @@ use namada_vote_ext::ethereum_tx_data_variants; use super::block_alloc::{BlockGas, BlockSpace}; use super::*; -use crate::facade::tendermint_proto::v0_37::abci::RequestProcessProposal; use crate::shell::block_alloc::{AllocFailure, TxBin}; use crate::shims::abcipp_shim_types::shim::response::ProcessProposal; use crate::shims::abcipp_shim_types::shim::TxBytes; +use crate::tendermint_proto::abci::RequestProcessProposal; /// Validation metadata, to keep track of used resources or /// transaction numbers, in a block proposal. diff --git a/crates/node/src/shell/snapshots.rs b/crates/node/src/shell/snapshots.rs index 921165a495..40572677f6 100644 --- a/crates/node/src/shell/snapshots.rs +++ b/crates/node/src/shell/snapshots.rs @@ -7,14 +7,13 @@ use namada_sdk::hash::{Hash, Sha256Hasher}; use namada_sdk::state::{BlockHeight, StorageRead}; use super::SnapshotSync; -use crate::facade::tendermint::abci::response::ApplySnapshotChunkResult; -use crate::facade::tendermint::abci::types::Snapshot; -use crate::facade::tendermint::v0_37::abci::{ - request as tm_request, response as tm_response, -}; use crate::shell::Shell; use crate::storage; use crate::storage::{DbSnapshot, DbSnapshotMeta}; +use crate::tendermint::abci::types::Snapshot; +use crate::tendermint::abci::{ + request as tm_request, response as tm_response, ApplySnapshotChunkResult, +}; pub const MAX_SENDER_STRIKES: u64 = 5; diff --git a/crates/node/src/shell/testing/client.rs b/crates/node/src/shell/testing/client.rs index 2a209c6f35..21ff520bff 100644 --- a/crates/node/src/shell/testing/client.rs +++ b/crates/node/src/shell/testing/client.rs @@ -94,7 +94,7 @@ pub fn run( #[async_trait::async_trait(?Send)] impl CliClient for MockNode { - fn from_tendermint_address(_: &crate::facade::tendermint_rpc::Url) -> Self { + fn from_tendermint_address(_: &crate::tendermint_rpc::Url) -> Self { unreachable!("MockNode should always be instantiated at test start.") } diff --git a/crates/node/src/shell/testing/node.rs b/crates/node/src/shell/testing/node.rs index e42d579857..a6e67d3987 100644 --- a/crates/node/src/shell/testing/node.rs +++ b/crates/node/src/shell/testing/node.rs @@ -48,20 +48,19 @@ use crate::ethereum_oracle::test_tools::mock_web3_client::{ use crate::ethereum_oracle::{ control, last_processed_block, try_process_eth_events, }; -use crate::facade::tendermint_proto::v0_37::abci::{ - RequestPrepareProposal, RequestProcessProposal, -}; -use crate::facade::tendermint_rpc::endpoint::block; -use crate::facade::tendermint_rpc::error::Error as RpcError; -use crate::facade::tendermint_rpc::SimpleRequest; -use crate::facade::{tendermint, tendermint_rpc}; use crate::shell::testing::utils::TestDir; use crate::shell::{EthereumOracleChannels, Shell}; use crate::shims::abcipp_shim_types::shim::request::{ FinalizeBlock, ProcessedTx, }; use crate::shims::abcipp_shim_types::shim::response::TxResult; -use crate::{dry_run_tx, storage}; +use crate::tendermint_proto::abci::{ + RequestPrepareProposal, RequestProcessProposal, +}; +use crate::tendermint_rpc::endpoint::block; +use crate::tendermint_rpc::error::Error as RpcError; +use crate::tendermint_rpc::SimpleRequest; +use crate::{dry_run_tx, storage, tendermint, tendermint_rpc}; /// Mock Ethereum oracle used for testing purposes. struct MockEthOracle { diff --git a/crates/node/src/shell/vote_extensions/bridge_pool_vext.rs b/crates/node/src/shell/vote_extensions/bridge_pool_vext.rs index b46dbd8a69..29104bebe3 100644 --- a/crates/node/src/shell/vote_extensions/bridge_pool_vext.rs +++ b/crates/node/src/shell/vote_extensions/bridge_pool_vext.rs @@ -140,19 +140,22 @@ mod test_bp_vote_extensions { Epoch::default(), ); let votes = vec![VoteInfo { - validator: crate::facade::tendermint::abci::types::Validator { + validator: crate::tendermint::abci::types::Validator { address: pkh1, - power: (u128::try_from(val1.bonded_stake).expect("Test failed") as u64).try_into().unwrap(), + power: (u128::try_from(val1.bonded_stake).expect("Test failed") + as u64) + .try_into() + .unwrap(), }, - sig_info: crate::facade::tendermint::abci::types::BlockSignatureInfo::LegacySigned, + sig_info: + crate::tendermint::abci::types::BlockSignatureInfo::LegacySigned, }]; let req = FinalizeBlock { proposer_address: pkh1.to_vec(), - decided_last_commit: - crate::facade::tendermint::abci::types::CommitInfo { - round: 0u8.into(), - votes, - }, + decided_last_commit: crate::tendermint::abci::types::CommitInfo { + round: 0u8.into(), + votes, + }, ..Default::default() }; assert_eq!(shell.start_new_epoch(Some(req)).0, 1); diff --git a/crates/node/src/shell/vote_extensions/eth_events.rs b/crates/node/src/shell/vote_extensions/eth_events.rs index 9dfbe59b48..c522c2bbb1 100644 --- a/crates/node/src/shell/vote_extensions/eth_events.rs +++ b/crates/node/src/shell/vote_extensions/eth_events.rs @@ -465,19 +465,22 @@ mod test_vote_extensions { Epoch::default(), ); let votes = vec![VoteInfo { - validator: crate::facade::tendermint::abci::types::Validator { + validator: crate::tendermint::abci::types::Validator { address: pkh1, - power: (u128::try_from(val1.bonded_stake).expect("Test failed") as u64).try_into().unwrap(), + power: (u128::try_from(val1.bonded_stake).expect("Test failed") + as u64) + .try_into() + .unwrap(), }, - sig_info: crate::facade::tendermint::abci::types::BlockSignatureInfo::LegacySigned, + sig_info: + crate::tendermint::abci::types::BlockSignatureInfo::LegacySigned, }]; let req = FinalizeBlock { proposer_address: pkh1.to_vec(), - decided_last_commit: - crate::facade::tendermint::abci::types::CommitInfo { - round: 0u8.into(), - votes, - }, + decided_last_commit: crate::tendermint::abci::types::CommitInfo { + round: 0u8.into(), + votes, + }, ..Default::default() }; assert_eq!(shell.start_new_epoch(Some(req)).0, 1); diff --git a/crates/node/src/shell/vote_extensions/val_set_update.rs b/crates/node/src/shell/vote_extensions/val_set_update.rs index 16e519c628..12a01830a5 100644 --- a/crates/node/src/shell/vote_extensions/val_set_update.rs +++ b/crates/node/src/shell/vote_extensions/val_set_update.rs @@ -315,19 +315,22 @@ mod test_vote_extensions { Epoch::default(), ); let votes = vec![VoteInfo { - validator: crate::facade::tendermint::abci::types::Validator { + validator: crate::tendermint::abci::types::Validator { address: pkh1, - power: (u128::try_from(val1.bonded_stake).expect("Test failed") as u64).try_into().unwrap(), + power: (u128::try_from(val1.bonded_stake).expect("Test failed") + as u64) + .try_into() + .unwrap(), }, - sig_info: crate::facade::tendermint::abci::types::BlockSignatureInfo::LegacySigned, + sig_info: + crate::tendermint::abci::types::BlockSignatureInfo::LegacySigned, }]; let req = FinalizeBlock { proposer_address: pkh1.to_vec(), - decided_last_commit: - crate::facade::tendermint::abci::types::CommitInfo { - round: 0u8.into(), - votes, - }, + decided_last_commit: crate::tendermint::abci::types::CommitInfo { + round: 0u8.into(), + votes, + }, ..Default::default() }; assert_eq!(shell.start_new_epoch(Some(req)).0, 1); diff --git a/crates/node/src/shims/abcipp_shim.rs b/crates/node/src/shims/abcipp_shim.rs index 6b37723b6a..5cccceb8bd 100644 --- a/crates/node/src/shims/abcipp_shim.rs +++ b/crates/node/src/shims/abcipp_shim.rs @@ -24,12 +24,10 @@ use super::abcipp_shim_types::shim::{ }; use crate::config; use crate::config::{Action, ActionAtHeight}; -use crate::facade::tendermint::v0_37::abci::{ - request, Request as Req, Response as Resp, -}; -use crate::facade::tower_abci::BoxError; use crate::shell::{EthereumOracleChannels, Shell}; use crate::storage::DbSnapshot; +use crate::tendermint::abci::{request, Request as Req, Response as Resp}; +use crate::tower_abci::BoxError; /// The shim wraps the shell, which implements ABCI++. /// The shim makes a crude translation between the ABCI interface currently used @@ -152,7 +150,7 @@ impl AbcippShim { .map_err(Error::from) .and_then(|res| match res { Response::FinalizeBlock(resp) => { - Ok(Resp::EndBlock(crate::facade::tendermint_proto::v0_37::abci::ResponseEndBlock::from(resp).try_into().unwrap())) + Ok(Resp::EndBlock(crate::tendermint_proto::abci::ResponseEndBlock::from(resp).try_into().unwrap())) } _ => Err(Error::ConvertResp(res)), }) diff --git a/crates/node/src/shims/abcipp_shim_types.rs b/crates/node/src/shims/abcipp_shim_types.rs index 32d53e20aa..620c78c989 100644 --- a/crates/node/src/shims/abcipp_shim_types.rs +++ b/crates/node/src/shims/abcipp_shim_types.rs @@ -1,4 +1,4 @@ -use crate::facade::tendermint::v0_37::abci::{Request, Response}; +use crate::tendermint::abci::{Request, Response}; pub mod shim { use std::fmt::Debug; @@ -8,10 +8,10 @@ pub mod shim { use thiserror::Error; use super::{Request as Req, Response as Resp}; - use crate::facade::tendermint::v0_37::abci::{ + use crate::shell; + use crate::tendermint::abci::{ request as tm_request, response as tm_response, }; - use crate::shell; pub type TxBytes = prost::bytes::Bytes; @@ -180,8 +180,8 @@ pub mod shim { use namada_sdk::tendermint::time::Time; use namada_sdk::time::DateTimeUtc; - use crate::facade::tendermint::abci::types::Misbehavior; - use crate::facade::tendermint::v0_37::abci::request as tm_request; + use crate::tendermint::abci::request as tm_request; + use crate::tendermint::abci::types::Misbehavior; pub struct VerifyHeader; @@ -316,13 +316,13 @@ pub mod shim { pub mod response { use namada_sdk::events::Event; - pub use crate::facade::tendermint::v0_37::abci::response::{ + pub use crate::tendermint::abci::response::{ PrepareProposal, ProcessProposal, }; - use crate::facade::tendermint_proto::v0_37::abci::{ + use crate::tendermint_proto::abci::{ Event as TmEvent, ValidatorUpdate, }; - use crate::facade::tendermint_proto::v0_37::types::ConsensusParams; + use crate::tendermint_proto::types::ConsensusParams; #[derive(Debug, Default)] pub struct VerifyHeader; @@ -343,9 +343,7 @@ pub mod shim { pub consensus_param_updates: Option, } - impl From - for crate::facade::tendermint_proto::v0_37::abci::ResponseEndBlock - { + impl From for crate::tendermint_proto::abci::ResponseEndBlock { fn from(resp: FinalizeBlock) -> Self { Self { events: resp diff --git a/crates/node/src/tendermint_node.rs b/crates/node/src/tendermint_node.rs index 32411a34cf..67336c0ad3 100644 --- a/crates/node/src/tendermint_node.rs +++ b/crates/node/src/tendermint_node.rs @@ -16,11 +16,9 @@ use tokio::process::{Child, Command}; use tokio::sync::oneshot::error::RecvError; use tokio::sync::oneshot::{Receiver, Sender}; -use crate::facade::tendermint::validator::Info; -use crate::facade::tendermint::{block, Genesis, Moniker, PublicKey}; -use crate::facade::tendermint_config::{ - Error as TendermintError, TendermintConfig, -}; +use crate::tendermint::validator::Info; +use crate::tendermint::{block, Genesis, Moniker, PublicKey}; +use crate::tendermint_config::{Error as TendermintError, TendermintConfig}; /// Env. var to output Tendermint log to stdout pub const ENV_VAR_TM_STDOUT: &str = "NAMADA_CMT_STDOUT"; diff --git a/crates/node/src/utils.rs b/crates/node/src/utils.rs index 913e2c718d..b2c02f40b2 100644 --- a/crates/node/src/utils.rs +++ b/crates/node/src/utils.rs @@ -10,7 +10,7 @@ use namada_sdk::address::{Address, ImplicitAddress}; use namada_sdk::key::common; use namada_sdk::wallet::FindKeyError; -use crate::facade::tendermint::Timeout; +use crate::tendermint::Timeout; pub fn test_genesis(args: TestGenesis, global_args: args::Global) { let TestGenesis { diff --git a/crates/sdk/src/queries/types.rs b/crates/sdk/src/queries/types.rs index 35970ab1fa..f5aeb2c298 100644 --- a/crates/sdk/src/queries/types.rs +++ b/crates/sdk/src/queries/types.rs @@ -5,8 +5,8 @@ use namada_state::{DBIter, StorageHasher, WlState, DB}; use thiserror::Error; use crate::events::log::EventLog; +pub use crate::tendermint::abci::request::Query as RequestQuery; use crate::tendermint::merkle::proof::ProofOps; -pub use crate::tendermint::v0_37::abci::request::Query as RequestQuery; /// A request context provides read-only access to storage and WASM compilation /// caches to request handlers. #[derive(Debug, Clone)] diff --git a/crates/tests/src/e2e/ibc_tests.rs b/crates/tests/src/e2e/ibc_tests.rs index 992f911586..694f1d52bb 100644 --- a/crates/tests/src/e2e/ibc_tests.rs +++ b/crates/tests/src/e2e/ibc_tests.rs @@ -24,9 +24,9 @@ use namada_apps_lib::client::utils::id_from_pk; use namada_apps_lib::config::genesis::{chain, templates}; use namada_apps_lib::config::utils::set_port; use namada_apps_lib::config::{ethereum_bridge, TendermintMode}; -use namada_apps_lib::facade::tendermint::block::Header as TmHeader; -use namada_apps_lib::facade::tendermint::merkle::proof::ProofOps as TmProof; -use namada_apps_lib::facade::tendermint_rpc::{Client, HttpClient, Url}; +use namada_apps_lib::tendermint::block::Header as TmHeader; +use namada_apps_lib::tendermint::merkle::proof::ProofOps as TmProof; +use namada_apps_lib::tendermint_rpc::{Client, HttpClient, Url}; use namada_core::string_encoding::StringEncoded; use namada_sdk::address::{Address, InternalAddress, MASP}; use namada_sdk::chain::{BlockHeight, Epoch}; diff --git a/crates/tests/src/e2e/ledger_tests.rs b/crates/tests/src/e2e/ledger_tests.rs index 07dd87e101..822400db5a 100644 --- a/crates/tests/src/e2e/ledger_tests.rs +++ b/crates/tests/src/e2e/ledger_tests.rs @@ -23,7 +23,7 @@ use namada_apps_lib::cli::context::ENV_VAR_CHAIN_ID; use namada_apps_lib::client::utils::PRE_GENESIS_DIR; use namada_apps_lib::config::utils::convert_tm_addr_to_socket_addr; use namada_apps_lib::config::{self, ethereum_bridge}; -use namada_apps_lib::facade::tendermint_config::net::Address as TendermintAddress; +use namada_apps_lib::tendermint_config::net::Address as TendermintAddress; use namada_apps_lib::wallet; use namada_core::chain::ChainId; use namada_core::token::NATIVE_MAX_DECIMAL_PLACES; diff --git a/crates/tests/src/integration/ledger_tests.rs b/crates/tests/src/integration/ledger_tests.rs index b5ca2372a6..fdd8d7233c 100644 --- a/crates/tests/src/integration/ledger_tests.rs +++ b/crates/tests/src/integration/ledger_tests.rs @@ -42,7 +42,7 @@ use crate::integration::setup; use crate::strings::{ TX_APPLIED_SUCCESS, TX_INSUFFICIENT_BALANCE, TX_REJECTED, }; -use crate::tendermint::abci::response::ApplySnapshotChunkResult; +use crate::tendermint::abci::ApplySnapshotChunkResult; use crate::tx::tx_host_env::gov_storage::proposal::{ PGFInternalTarget, PGFTarget, }; @@ -1755,7 +1755,7 @@ fn enforce_fee_payment() -> Result<()> { /// from one node to another. #[test] fn apply_snapshot() -> Result<()> { - use namada_node::facade::tendermint::v0_37::abci::{ + use namada_node::tendermint::abci::{ request as tm_request, response as tm_response, }; // This address doesn't matter for tests. But an argument is required. @@ -1880,7 +1880,7 @@ fn apply_snapshot() -> Result<()> { /// Test the various failure conditions of state sync #[test] fn snapshot_unhappy_flows() -> Result<()> { - use namada_node::facade::tendermint::v0_37::abci::{ + use namada_node::tendermint::abci::{ request as tm_request, response as tm_response, }; let (node, _services) = setup::setup()?; diff --git a/crates/tests/src/integration/setup.rs b/crates/tests/src/integration/setup.rs index 524df788bf..fc472e8a6e 100644 --- a/crates/tests/src/integration/setup.rs +++ b/crates/tests/src/integration/setup.rs @@ -12,8 +12,8 @@ use namada_apps_lib::config::genesis::chain::Finalized; use namada_apps_lib::config::genesis::templates; use namada_apps_lib::config::genesis::templates::load_and_validate; use namada_apps_lib::config::TendermintMode; -use namada_apps_lib::facade::tendermint::Timeout; -use namada_apps_lib::facade::tendermint_proto::google::protobuf::Timestamp; +use namada_apps_lib::tendermint::Timeout; +use namada_apps_lib::tendermint_proto::google::protobuf::Timestamp; use namada_apps_lib::wallet::defaults::derive_template_dir; use namada_apps_lib::wallet::pre_genesis; use namada_core::chain::ChainIdPrefix; @@ -229,7 +229,7 @@ fn create_node( auto_drive_services, }; let init_req = - namada_apps_lib::facade::tendermint::v0_37::abci::request::InitChain { + namada_apps_lib::tendermint::abci::request::InitChain { time: Timestamp { seconds: 0, nanos: 0, @@ -237,23 +237,23 @@ fn create_node( .try_into().unwrap(), chain_id: chain_id.to_string(), consensus_params: - namada_apps_lib::facade::tendermint::consensus::params::Params { - block: namada_apps_lib::facade::tendermint::block::Size { + namada_apps_lib::tendermint::consensus::params::Params { + block: namada_apps_lib::tendermint::block::Size { max_bytes: 0, max_gas: 0, time_iota_ms: 0, }, evidence: - namada_apps_lib::facade::tendermint::evidence::Params { + namada_apps_lib::tendermint::evidence::Params { max_age_num_blocks: 0, - max_age_duration: namada_apps_lib::facade::tendermint::evidence::Duration(core::time::Duration::MAX), + max_age_duration: namada_apps_lib::tendermint::evidence::Duration(core::time::Duration::MAX), max_bytes: 0, }, - validator: namada_apps_lib::facade::tendermint::consensus::params::ValidatorParams { + validator: namada_apps_lib::tendermint::consensus::params::ValidatorParams { pub_key_types: vec![] }, version: None, - abci: namada_apps_lib::facade::tendermint::consensus::params::AbciParams { + abci: namada_apps_lib::tendermint::consensus::params::AbciParams { vote_extensions_enable_height: None, }, }, diff --git a/fuzz/fuzz_targets/txs_prepare_proposal.rs b/fuzz/fuzz_targets/txs_prepare_proposal.rs index 444eb2e6b7..66a68dcbfa 100644 --- a/fuzz/fuzz_targets/txs_prepare_proposal.rs +++ b/fuzz/fuzz_targets/txs_prepare_proposal.rs @@ -2,10 +2,10 @@ use lazy_static::lazy_static; use libfuzzer_sys::fuzz_target; -use namada_node::facade::tendermint_proto::v0_37::abci::RequestPrepareProposal; use namada_node::shell; use namada_node::shell::test_utils::TestShell; use namada_node::shims::abcipp_shim_types::shim::TxBytes; +use namada_node::tendermint_proto::abci::RequestPrepareProposal; use namada_tx::Tx; lazy_static! { From a899f28511eb8f2af4920da47d917ca5aaa5a3c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Zemanovi=C4=8D?= Date: Fri, 23 Aug 2024 13:11:24 +0100 Subject: [PATCH 2/2] changelog: add #3697 --- .../unreleased/improvements/3697-refactor-tm-reexports.md | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 .changelog/unreleased/improvements/3697-refactor-tm-reexports.md diff --git a/.changelog/unreleased/improvements/3697-refactor-tm-reexports.md b/.changelog/unreleased/improvements/3697-refactor-tm-reexports.md new file mode 100644 index 0000000000..f20855feaf --- /dev/null +++ b/.changelog/unreleased/improvements/3697-refactor-tm-reexports.md @@ -0,0 +1,2 @@ +- Only re-exporting tendermint-rs v0.37 modules. + ([\#3697](https://github.com/anoma/namada/pull/3697)) \ No newline at end of file