Skip to content

Implement connection retry and timeout using tower-service #352

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 127 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
d6776da
undefined behavior on simultaneous read or write
Buckram123 Feb 12, 2024
24950a3
use handles
Buckram123 Feb 12, 2024
b40fcf5
let it finish
Buckram123 Feb 12, 2024
22d5f3f
POC
Buckram123 Feb 13, 2024
d743384
add force write
Buckram123 Feb 13, 2024
56da24f
drop guard if not used
Buckram123 Feb 14, 2024
0f301a6
should not be able to edit read-only
Buckram123 Feb 14, 2024
3161232
create cw-orch service
CyberHoward Mar 26, 2024
acd8d75
Merge remote-tracking branch 'origin/main' into daemon-state-ub
Buckram123 Apr 19, 2024
687c079
clean ups and more tests
Buckram123 Apr 19, 2024
fa74aaa
update comment on Global Write State
Buckram123 Apr 22, 2024
7d4e19f
update comment for global write state
Buckram123 Apr 22, 2024
0a856c7
Merge branch 'main' into daemon-state-ub
Buckram123 Apr 22, 2024
a2d860c
remove var to fix tests
Buckram123 Apr 22, 2024
8bdd5b9
Merge remote-tracking branch 'origin/main' into daemon-state-ub
Buckram123 May 3, 2024
a6b881f
Allow cloning locked state
Buckram123 May 6, 2024
eb23921
minimize mutex lock impact progress
Buckram123 May 6, 2024
ee5b4c2
move channel to sender
Buckram123 May 7, 2024
2c9b040
add some tests
Buckram123 May 7, 2024
b8259e8
remove unused code
Buckram123 May 7, 2024
f793b18
Merge remote-tracking branch 'origin/main' into daemon-state-ub
Buckram123 May 7, 2024
fafd27a
fix tests
Buckram123 May 7, 2024
d4f8e46
add error handling
Buckram123 May 7, 2024
d8d44ca
add drop tests
Buckram123 May 7, 2024
79a36b7
fix rest of the tests
Buckram123 May 7, 2024
d84d515
apply Robin review
Buckram123 May 9, 2024
e923332
restore cw-orch-core
Buckram123 May 9, 2024
9cdce4f
restore tube
Buckram123 May 9, 2024
6a5c1ec
Continued experimentation
Kayanski May 13, 2024
ee25335
Update cw-orch-daemon/src/state.rs
Buckram123 May 15, 2024
2370365
Update cw-orch-daemon/src/state.rs
Buckram123 May 15, 2024
cdb5cee
More traits
Kayanski May 20, 2024
b569702
More changes, almost there
Kayanski May 21, 2024
04a35b6
Added multiple sender
Kayanski May 22, 2024
baed9b1
Update outdated comment
Buckram123 Jun 4, 2024
85de796
remove outdated comments
Buckram123 Jun 4, 2024
4eda129
Merge remote-tracking branch 'origin/main' into daemon-state-ub
Buckram123 Jun 4, 2024
c20f685
post-merge fixes
Buckram123 Jun 4, 2024
e3d489e
update changelog
Buckram123 Jun 4, 2024
43a8773
Merge with main
Kayanski Jun 5, 2024
4d84f51
Nicoco nits
Buckram123 Jun 5, 2024
e96f224
Getting there
Kayanski Jun 5, 2024
9d259ed
private `state_path` and fix grpc connection
Buckram123 Jun 5, 2024
02c624b
Fix all issues, but one
Kayanski Jun 5, 2024
b9f54a1
need to unset state env
Buckram123 Jun 5, 2024
eadc089
fix write, for cases where new file smaller than original(for example…
Buckram123 Jun 5, 2024
0ff395f
add flush where it's needed
Buckram123 Jun 5, 2024
a795bbe
ignore toxic test
Buckram123 Jun 5, 2024
499486a
Fixed everything, wallets are allowed
Kayanski Jun 6, 2024
5a71668
Merged and remove cosmwasm generic
Kayanski Jun 6, 2024
1c9a7ab
Added multisender example
Kayanski Jun 6, 2024
0c1a007
Added multidaemon type
Kayanski Jun 6, 2024
2826633
Merge with main
Kayanski Jun 6, 2024
95a353b
Fix re-export
Kayanski Jun 6, 2024
eadf4af
fix doc tests
Kayanski Jun 6, 2024
1febcf7
Merge branch 'main' into nicolas/orc-126-daemon-should-become-a-wrapp…
Kayanski Jun 9, 2024
f9d9693
Added manual sender
Kayanski Jun 11, 2024
ec728dd
Added manual sender example
Kayanski Jun 11, 2024
95b788a
formatting
Kayanski Jun 11, 2024
6e3b1ca
merged
Kayanski Jun 18, 2024
a346e5a
formatting
Kayanski Jun 18, 2024
c847ab8
Using mnemonic inside options
Kayanski Jun 18, 2024
51c9b8c
Added mrsv for async traits
Kayanski Jun 18, 2024
57d8a31
merge
Kayanski Jun 19, 2024
079ee2a
Removed one packet assertion
Kayanski Jun 19, 2024
e1f1f64
Nit
Kayanski Jun 19, 2024
23b0d7b
Update contracts/counter/examples/manual-sender.rs
Kayanski Jun 25, 2024
ba1f265
Update cw-orch-daemon/src/builder.rs
Kayanski Jun 25, 2024
b8899cb
Nits
Kayanski Jun 25, 2024
0d4660a
Merge branch 'nicolas/orc-126-daemon-should-become-a-wrapper-around-s…
Kayanski Jun 25, 2024
c654a80
Nits
Kayanski Jun 25, 2024
ca87a14
Moved manual sender, added querier-daemon
Kayanski Jun 27, 2024
4bc002d
Merge with main
Kayanski Jun 27, 2024
62ebe25
Merge remote-tracking branch 'origin/main' into feature/service
CyberHoward Jun 28, 2024
6b49536
get retry layer working
CyberHoward Jun 28, 2024
17b040e
format
CyberHoward Jun 28, 2024
0acd362
play around further with service traits
CyberHoward Jun 28, 2024
97f67d6
compile
CyberHoward Jun 28, 2024
1a18cf1
formatting
CyberHoward Jun 28, 2024
e520ce2
fix compile
CyberHoward Jun 28, 2024
bedebe1
fix compile
CyberHoward Jun 28, 2024
a551851
impl service
CyberHoward Jul 1, 2024
d970e18
nit renames
CyberHoward Jul 1, 2024
fa2dee3
split up traits to enable finer implementations
CyberHoward Jul 1, 2024
d317158
propagate query traits
CyberHoward Jul 1, 2024
cd9609c
fix compilation
CyberHoward Jul 1, 2024
671e5ae
apply nits
CyberHoward Jul 2, 2024
7bf8a19
tests compile
Buckram123 Jul 2, 2024
1ab44b8
clippy
Buckram123 Jul 2, 2024
2b36448
fix tests for all targets and features
Buckram123 Jul 2, 2024
5f0d0ff
docs fix
Buckram123 Jul 2, 2024
b13557a
add chain constructor to builder and move around internal impl
CyberHoward Jul 2, 2024
8648684
move around sync builder impl
CyberHoward Jul 2, 2024
534c6d2
rename and restructure sender files
CyberHoward Jul 3, 2024
c423179
Simplify sender traits
CyberHoward Jul 3, 2024
d80978b
reflect re-exports in cw-orch
CyberHoward Jul 3, 2024
4d62b76
refactor exports
CyberHoward Jul 3, 2024
8736864
make daemon hold RwLock of Sender
CyberHoward Jul 3, 2024
53f32f2
make state hold Arc<ChainInfo>
CyberHoward Jul 3, 2024
202255e
create channel from reference chaininfo
CyberHoward Jul 3, 2024
09cfc9e
update examples
CyberHoward Jul 3, 2024
cb66466
update builders
CyberHoward Jul 3, 2024
820f728
update queriers
CyberHoward Jul 3, 2024
33398da
update tests
CyberHoward Jul 3, 2024
5f6e6bc
rename QuerySender `grpc_channel` fn to `channel`
CyberHoward Jul 3, 2024
65dda21
Remove `chain_info` fn from QuerySender
CyberHoward Jul 3, 2024
0d39d82
clippy
CyberHoward Jul 3, 2024
910152d
clippy
CyberHoward Jul 3, 2024
0dc729c
update exports and examples
CyberHoward Jul 3, 2024
120cd67
don't use Arc RwLock for sender
CyberHoward Jul 5, 2024
c8f9a89
rename `set_sender` to `new_sender` to prevent conflict with `TxHandl…
CyberHoward Jul 5, 2024
e08dbca
nits on senders
CyberHoward Jul 5, 2024
4acf937
fix examples
CyberHoward Jul 5, 2024
96cb052
add `sender_addr` function to `TxHandler` and deprecate `.sender`
CyberHoward Jul 5, 2024
652def8
update tests
CyberHoward Jul 5, 2024
927800b
implement `sender_addr` for environments
CyberHoward Jul 5, 2024
cb91005
replace uses of `.sender` with `.sender_addr`
CyberHoward Jul 5, 2024
f2be786
rm `sender_addr` from daemon
CyberHoward Jul 5, 2024
f4cfe59
fix tests
CyberHoward Jul 5, 2024
6774e1e
final test changes
CyberHoward Jul 5, 2024
2d47230
format
CyberHoward Jul 5, 2024
725c25d
remove `QueryOnlySenderOptions` in favor of `()`
CyberHoward Jul 5, 2024
3e1ad12
fix rename
CyberHoward Jul 5, 2024
2b7938a
rm unused import
CyberHoward Jul 5, 2024
20c69d9
Merge branch 'main' into sender_refactor
CyberHoward Jul 5, 2024
a2104b6
Merge remote-tracking branch 'origin/sender_refactor' into feature/se…
CyberHoward Jul 5, 2024
419ea7d
update channel to service
CyberHoward Jul 8, 2024
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
2 changes: 1 addition & 1 deletion contracts/counter/examples/async.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub async fn main() -> anyhow::Result<()> {
pretty_env_logger::init(); // Used to log contract and chain interactions

let network = networks::LOCAL_JUNO;
let chain = DaemonAsyncBuilder::default().chain(network).build().await?;
let chain = DaemonAsyncBuilder::new(network).build().await?;

let counter = CounterContract::new(chain);

Expand Down
2 changes: 1 addition & 1 deletion contracts/counter/examples/deploy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ pub fn main() -> anyhow::Result<()> {
pretty_env_logger::init(); // Used to log contract and chain interactions

let network = networks::LOCAL_JUNO;
let chain = DaemonBuilder::default().chain(network).build()?;
let chain = DaemonBuilder::new(network).build()?;
// ANCHOR_END: chain_construction

// ANCHOR: contract_interaction
Expand Down
2 changes: 1 addition & 1 deletion contracts/counter/tests/osmosis-test-tube.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ fn setup<Chain: CwEnv>(chain: Chain) -> CounterContract<Chain> {
// Instantiate the contract
let msg = InstantiateMsg { count: 1i32 };
let init_resp = contract
.instantiate(&msg, Some(&chain.sender()), None)
.instantiate(&msg, Some(&chain.sender_addr()), None)
.unwrap();

// Get the address from the response
Expand Down
8 changes: 7 additions & 1 deletion cw-orch-daemon/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ chrono = { version = "0.4" }
base16 = { version = "0.2.1" }
ring = { version = "0.17.3" }
dirs = "5.0.1"

tower = { version = "0.4", features = ["retry", "reconnect"] }

# Injective dependencies
ethers-signers = { version = "2.0.7", optional = true }
Expand All @@ -66,6 +66,8 @@ async-recursion = "1.0.5"
# Gzip
flate2 = { version = "1.0.26" }
lazy_static = "1.4.0"
http = "0.2.11"
hyper = "0.14.27"

# Lock daemon
file-lock = { version = "2.1.10" }
Expand All @@ -74,6 +76,7 @@ regex = "1.10.4"

[dev-dependencies]
cw-orch-daemon = { path = "." }
cw-orch = { path = "../cw-orch", features = ["daemon"] }
uid = "0.1.7"
env_logger = "0.11.2"
cw20 = { version = "1" }
Expand All @@ -94,3 +97,6 @@ tokio-test = "0.4.3"

# File lock test
nix = { version = "0.28.0", features = ["process"] }
counter-contract = { path = "../contracts/counter" }
dotenv = "0.15.0"
pretty_env_logger = "0.5.0"
49 changes: 49 additions & 0 deletions cw-orch-daemon/examples/batch-sender.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// ANCHOR: full_counter_example
use counter_contract::{
msg::InstantiateMsg, CounterContract, CounterExecuteMsgFns, CounterQueryMsgFns,
};
use cw_orch::{anyhow, daemon::senders::BatchDaemon, prelude::*};
use cw_orch_daemon::senders::CosmosBatchOptions;

// From https://github.com/CosmosContracts/juno/blob/32568dba828ff7783aea8cb5bb4b8b5832888255/docker/test-user.env#L2
const LOCAL_MNEMONIC: &str = "clip hire initial neck maid actor venue client foam budget lock catalog sweet steak waste crater broccoli pipe steak sister coyote moment obvious choose";
pub fn main() -> anyhow::Result<()> {
std::env::set_var("LOCAL_MNEMONIC", LOCAL_MNEMONIC);
dotenv::dotenv().ok(); // Used to load the `.env` file if any
pretty_env_logger::init(); // Used to log contract and chain interactions

let network = networks::LOCAL_JUNO;
let chain: BatchDaemon =
BatchDaemon::builder(network).build_sender(CosmosBatchOptions::default())?;

let counter = CounterContract::new(chain.clone());

counter.upload()?;
counter.instantiate(&InstantiateMsg { count: 0 }, None, None)?;

counter.increment()?;

// The count hasn't been incremented yet, we didn't broadcast the tx
let count = counter.get_count()?;
assert_eq!(count.count, 0);

chain.rt_handle.block_on(chain.sender().broadcast(None))?;

let count = counter.get_count()?;
assert_eq!(count.count, 1);

// Increment multiple times in the same transaction
counter.increment()?;
counter.increment()?;
counter.increment()?;
counter.increment()?;
counter.increment()?;
counter.increment()?;

chain.rt_handle.block_on(chain.sender().broadcast(None))?;

let count = counter.get_count()?;
assert_eq!(count.count, 7);

Ok(())
}
6 changes: 4 additions & 2 deletions cw-orch-daemon/examples/daemon-capabilities.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::str::FromStr;
use cosmrs::{tx::Msg, AccountId, Coin, Denom};
use cosmwasm_std::coins;
// ANCHOR: full_counter_example
use cw_orch_daemon::senders::tx::TxSender;
use cw_orch_daemon::DaemonBuilder;
use cw_orch_networks::networks;

Expand All @@ -12,13 +13,14 @@ pub fn main() -> anyhow::Result<()> {
std::env::set_var("LOCAL_MNEMONIC", LOCAL_MNEMONIC);

let network = networks::LOCAL_JUNO;
let mut daemon = DaemonBuilder::default().chain(network).build()?;
let mut daemon = DaemonBuilder::new(network).build()?;

daemon.flush_state()?;

// We commit the tx (also resimulates the tx)
// ANCHOR: send_tx
let wallet = daemon.wallet();
let wallet = daemon.sender();

let rt = daemon.rt_handle.clone();
rt.block_on(wallet.bank_send("<address-of-my-sister>", coins(345, "ujunox")))?;
// ANCHOR_END: send_tx
Expand Down
196 changes: 196 additions & 0 deletions cw-orch-daemon/examples/manual_sender.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,196 @@
// This file illustrates an example for custom sender inside Daemon

use cw_orch_daemon::proto::injective::InjectiveEthAccount;
use cw_orch_daemon::queriers::Node;
use cw_orch_daemon::senders::builder::SenderBuilder;
use cw_orch_daemon::senders::query::QuerySender;
use cw_orch_daemon::tx_broadcaster::assert_broadcast_code_cosm_response;
use cw_orch_daemon::{DaemonBase, GrpcChannel, TxBuilder};

use cw_orch_daemon::{CosmTxResponse, DaemonError};

use cosmrs::proto::cosmos;
use cosmrs::proto::cosmos::auth::v1beta1::BaseAccount;
use cosmrs::proto::cosmos::vesting::v1beta1::PeriodicVestingAccount;
use cosmrs::tendermint::chain::Id;
use cosmrs::tx::{ModeInfo, Raw, SignDoc, SignMode, SignerInfo};
use cosmrs::{AccountId, Any};
use cosmwasm_std::Addr;
use cw_orch::prelude::*;
use cw_orch_core::environment::ChainInfoOwned;
use prost::Message;
use std::io::{self, Write};
use std::sync::Arc;
use tonic::transport::Channel;

// ANCHOR: full_counter_example
use counter_contract::CounterContract;

// This is a test with a manual sender, to verify everything works, nothing is broadcasted

pub fn main() -> anyhow::Result<()> {
dotenv::dotenv().ok(); // Used to load the `.env` file if any
pretty_env_logger::init(); // Used to log contract and chain interactions

let network = cw_orch_networks::networks::JUNO_1;
let sender = "juno1xjf5xscdk08c5es2m7epmerrpqmkmc3n98650t";
let chain: ManualDaemon = ManualDaemon::builder(network).build_sender(ManualSenderOptions {
sender_address: sender.to_string(),
})?;

let counter = CounterContract::new(chain.clone());

// Example tx hash that succeed (correspond to a code upload tx)
// 58AA802705BEE4597A560FBC67F6C86400E66F5FCBD0F08AA37FB140BCD65B6D
// If not found, try to find the latests juno code uploaded (4380+)
// https://www.mintscan.io/juno/wasm/code/4380
counter.upload()?;

Ok(())
}

use cw_orch_daemon::senders::tx::TxSender;

pub type ManualDaemon = DaemonBase<ManualSender>;

#[derive(Clone, Default)]
pub struct ManualSenderOptions {
pub sender_address: String,
}

/// Signer of the transactions and helper for address derivation
/// This is the main interface for simulating and signing transactions
#[derive(Clone)]
pub struct ManualSender {
pub sender: Addr,
pub chain_info: Arc<ChainInfoOwned>,
pub grpc_channel: Channel,
}

impl SenderBuilder for ManualSenderOptions {
type Error = DaemonError;
type Sender = ManualSender;

async fn build(&self, chain_info: &Arc<ChainInfoOwned>) -> Result<ManualSender, Self::Error> {
let grpc_channel = GrpcChannel::from_chain_info(chain_info.as_ref()).await?;
Ok(ManualSender {
chain_info: chain_info.clone(),
sender: Addr::unchecked(self.sender_address.clone()),
grpc_channel,
})
}
}

impl QuerySender for ManualSender {
type Error = DaemonError;
type Options = ManualSenderOptions;

fn channel(&self) -> tonic::transport::Channel {
self.grpc_channel.clone()
}
}

impl TxSender for ManualSender {
async fn commit_tx_any(
&self,
msgs: Vec<Any>,
memo: Option<&str>,
) -> Result<CosmTxResponse, DaemonError> {
// We print the any messages to broadcast
println!("Here is the transaction to sign and broadcast: ");
println!("{:?}", msgs);
// We simulate
let gas_needed = self.simulate(msgs, memo).await?;
println!("Gas needed: {}", gas_needed);

// We wait for the txhash as input to be able to continue the execution
println!("Enter the txhash to proceed");
let mut txhash = String::new();
io::stdout().flush().unwrap(); // Ensure the prompt is displayed
io::stdin()
.read_line(&mut txhash)
.expect("Failed to read line");
let txhash = txhash.trim_end();

let resp = Node::new_async(self.channel())
._find_tx(txhash.to_string())
.await?;

assert_broadcast_code_cosm_response(resp)
}

fn account_id(&self) -> AccountId {
self.sender.clone().to_string().parse().unwrap()
}
}

impl ManualSender {
pub async fn simulate(&self, msgs: Vec<Any>, memo: Option<&str>) -> Result<u64, DaemonError> {
let timeout_height = Node::new_async(self.channel())._block_height().await? + 10u64;

let tx_body = TxBuilder::build_body(msgs, memo, timeout_height);

let fee = TxBuilder::build_fee(0u8, &self.chain_info.gas_denom, 0, None)?;

let BaseAccount {
account_number,
sequence,
pub_key,
..
} = self.base_account().await?;

let auth_info = SignerInfo {
public_key: pub_key.map(|key| key.try_into()).transpose()?,
mode_info: ModeInfo::single(SignMode::Direct),
sequence,
}
.auth_info(fee);

let sign_doc = SignDoc::new(
&tx_body,
&auth_info,
&Id::try_from(self.chain_info.chain_id.to_string())?,
account_number,
)?;

let tx_raw: Raw = cosmos::tx::v1beta1::TxRaw {
body_bytes: sign_doc.body_bytes,
auth_info_bytes: sign_doc.auth_info_bytes,
signatures: vec![vec![]],
}
.into();

Node::new_async(self.channel())
._simulate_tx(tx_raw.to_bytes()?)
.await
}

async fn base_account(&self) -> Result<BaseAccount, DaemonError> {
let addr = self.address().to_string();

let mut client =
cosmrs::proto::cosmos::auth::v1beta1::query_client::QueryClient::new(self.channel());

let resp = client
.account(cosmrs::proto::cosmos::auth::v1beta1::QueryAccountRequest { address: addr })
.await?
.into_inner();

let account = resp.account.unwrap().value;

let acc = if let Ok(acc) = BaseAccount::decode(account.as_ref()) {
acc
} else if let Ok(acc) = PeriodicVestingAccount::decode(account.as_ref()) {
// try vesting account, (used by Terra2)
acc.base_vesting_account.unwrap().base_account.unwrap()
} else if let Ok(acc) = InjectiveEthAccount::decode(account.as_ref()) {
acc.base_account.unwrap()
} else {
return Err(DaemonError::StdErr(
"Unknown account type returned from QueryAccountRequest".into(),
));
};

Ok(acc)
}
}
20 changes: 20 additions & 0 deletions cw-orch-daemon/examples/querier-daemon.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// ANCHOR: full_counter_example

use cw_orch::{anyhow, prelude::*};
use cw_orch_daemon::senders::QueryOnlyDaemon;

// From https://github.com/CosmosContracts/juno/blob/32568dba828ff7783aea8cb5bb4b8b5832888255/docker/test-user.env#L1
pub const LOCAL_JUNO_SENDER: &str = "juno16g2rahf5846rxzp3fwlswy08fz8ccuwk03k57y";

pub fn main() -> anyhow::Result<()> {
pretty_env_logger::init(); // Used to log contract and chain interactions

let network = networks::LOCAL_JUNO;
// There is no need to register a mnemonic to use this daemon querier
let chain: QueryOnlyDaemon = QueryOnlyDaemon::builder(network).build_sender(())?;

let balances = chain.bank_querier().balance(LOCAL_JUNO_SENDER, None)?;
assert!(!balances.is_empty());

Ok(())
}
Loading
Loading