Skip to content

Commit

Permalink
Added ability to define protocol version when serializing (#34)
Browse files Browse the repository at this point in the history
* Added ability to define protocol version when serializing

* Switched default protocol version. Expanding RPC Server Capabilities

* RPC server changes

* Fixed Missing Import for metrics build

* Fixed coin selection, changed from static refs to Arcs and cleaned up proof of space code

* Version Bump to 2.0.3
  • Loading branch information
DaOneLuna authored Apr 10, 2024
1 parent f518b38 commit 86a6640
Show file tree
Hide file tree
Showing 51 changed files with 2,223 additions and 1,375 deletions.
15 changes: 8 additions & 7 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dg_xch_cli"
version = "2.0.2"
version = "2.0.3"
edition = "2021"
authors = ["James Hoerr"]
description = "CLI Utilities for the Chia Blockchain"
Expand All @@ -22,12 +22,13 @@ bip39 = {version= "2.0.0", features=["rand"] }
blst = { version = "0.3.11", features = ["portable"] }
clap = { version = "4.5.1", features = ["derive"] }
dashmap = "5.5.3"
dg_xch_clients = {path = "../clients", version="2.0.2"}
dg_xch_core = {path = "../core", version = "2.0.2", default-features = false}
dg_xch_keys = {path = "../keys", version="2.0.2"}
dg_xch_pos = {path = "../proof_of_space", version="2.0.2"}
dg_xch_puzzles = {path = "../puzzles", version="2.0.2"}
dg_xch_serialize= {path = "../serialize", version="2.0.2"}
dialoguer = "0.11.0"
dg_xch_clients = {path = "../clients", version="2.0.3"}
dg_xch_core = {path = "../core", version = "2.0.3", default-features = false}
dg_xch_keys = {path = "../keys", version="2.0.3"}
dg_xch_pos = {path = "../proof_of_space", version="2.0.3"}
dg_xch_puzzles = {path = "../puzzles", version="2.0.3"}
dg_xch_serialize= {path = "../serialize", version="2.0.3"}
hex = "0.4.3"
lazy_static = "1.4.0"
log = "0.4.20"
Expand Down
38 changes: 38 additions & 0 deletions cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use bip39::Mnemonic;
use clap::{Parser, Subcommand};
use dg_xch_core::blockchain::sized_bytes::Bytes32;
use dialoguer::theme::ColorfulTheme;
use dialoguer::Input;
use std::io::{Error, ErrorKind};
use std::str::FromStr;

#[derive(Parser, Debug)]
#[command(author, version, about, long_about = None)]
Expand All @@ -25,6 +30,12 @@ pub struct Cli {

#[derive(Debug, Subcommand)]
pub enum RootCommands {
//START OF FULLNODE API
#[command(about = "Get the current BlockchainState", long_about = None)]
PrintPlottingInfo {
#[arg(long)]
launcher_id: Option<Bytes32>,
},
//START OF FULLNODE API
#[command(about = "Get the current BlockchainState", long_about = None)]
GetBlockchainState,
Expand Down Expand Up @@ -313,3 +324,30 @@ pub enum WalletAction {
#[command(about = "Creates a Cold wallet", long_about = None)]
Cold,
}

pub fn prompt_for_mnemonic() -> Result<Mnemonic, Error> {
Mnemonic::from_str(
&Input::<String>::with_theme(&ColorfulTheme::default())
.with_prompt("Please Input Your Mnemonic: ")
.validate_with(|input: &String| -> Result<(), &str> {
if Mnemonic::from_str(input).is_ok() {
Ok(())
} else {
Err("You did not input a valid Mnemonic, Please try again.")
}
})
.interact_text()
.map_err(|e| {
Error::new(
ErrorKind::InvalidInput,
format!("Failed to read user Input for Mnemonic: {e:?}"),
)
})?,
)
.map_err(|e| {
Error::new(
ErrorKind::InvalidInput,
format!("Failed to parse Mnemonic: {e:?}"),
)
})
}
87 changes: 83 additions & 4 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@ use cli::*;
use dg_xch_cli::wallet_commands::{
create_cold_wallet, get_plotnft_ready_state, migrate_plot_nft, migrate_plot_nft_with_owner_key,
};
use dg_xch_cli::wallets::plotnft_utils::{get_plotnft_by_launcher_id, scrounge_for_plotnfts};
use dg_xch_clients::api::full_node::{FullnodeAPI, FullnodeExtAPI};
use dg_xch_clients::api::pool::create_pool_login_url;
use dg_xch_clients::rpc::full_node::FullnodeClient;
use dg_xch_clients::ClientSSLConfig;
use dg_xch_core::blockchain::sized_bytes::Bytes32;
use dg_xch_core::blockchain::sized_bytes::{Bytes32, Bytes48};
use dg_xch_core::blockchain::spend_bundle::SpendBundle;
use dg_xch_serialize::ChiaSerialize;
use dg_xch_keys::{
encode_puzzle_hash, key_from_mnemonic, master_sk_to_farmer_sk, master_sk_to_pool_sk,
master_sk_to_wallet_sk, master_sk_to_wallet_sk_unhardened,
};
use dg_xch_puzzles::clvm_puzzles::launcher_id_to_p2_puzzle_hash;
use dg_xch_puzzles::p2_delegated_puzzle_or_hidden_puzzle::puzzle_hash_for_pk;
use dg_xch_serialize::{ChiaProtocolVersion, ChiaSerialize};
use hex::decode;
use log::{error, info, LevelFilter};
use simple_logger::SimpleLogger;
use std::env;
use std::io::{Cursor, Error};
use std::io::{Cursor, Error, ErrorKind};
use std::sync::Arc;

#[tokio::main]
Expand All @@ -44,6 +51,78 @@ async fn main() -> Result<(), Error> {
ssl_ca_crt_path: format!("{}/{}", v, "full_node/private_full_node.crt"),
});
match cli.action {
RootCommands::PrintPlottingInfo { launcher_id } => {
let client = Arc::new(FullnodeClient::new(&host, port, timeout, ssl, &None));
let master_key = key_from_mnemonic(&prompt_for_mnemonic()?)?;
let mut page = 0;
let mut plotnfts = vec![];
if let Some(launcher_id) = launcher_id {
info!("Searching for NFT with LauncherID: {launcher_id}");
if let Some(plotnft) =
get_plotnft_by_launcher_id(client.clone(), &launcher_id).await?
{
plotnfts.push(plotnft);
} else {
return Err(Error::new(
ErrorKind::NotFound,
"Failed to find a plotNFT with LauncherID: {launcher_id}",
));
}
} else {
info!("No LauncherID Specified, Searching for PlotNFTs...");
while page < 50 && plotnfts.is_empty() {
let mut puzzle_hashes = vec![];
for index in page * 50..(page + 1) * 50 {
let wallet_sk = master_sk_to_wallet_sk_unhardened(&master_key, index)
.map_err(|e| {
Error::new(
ErrorKind::InvalidInput,
format!("Failed to parse Wallet SK: {:?}", e),
)
})?;
let pub_key: Bytes48 = wallet_sk.sk_to_pk().to_bytes().into();
puzzle_hashes.push(puzzle_hash_for_pk(&pub_key)?);
let hardened_wallet_sk = master_sk_to_wallet_sk(&master_key, index)
.map_err(|e| {
Error::new(
ErrorKind::InvalidInput,
format!("Failed to parse Wallet SK: {:?}", e),
)
})?;
let pub_key: Bytes48 = hardened_wallet_sk.sk_to_pk().to_bytes().into();
puzzle_hashes.push(puzzle_hash_for_pk(&pub_key)?);
}
plotnfts.extend(scrounge_for_plotnfts(client.clone(), &puzzle_hashes).await?);
page += 1;
}
}
let farmer_key =
Bytes48::from(master_sk_to_farmer_sk(&master_key)?.sk_to_pk().to_bytes());
let pool_key = Bytes48::from(master_sk_to_pool_sk(&master_key)?.sk_to_pk().to_bytes());
info!("{{");
info!("\tFarmerPublicKey(All Plots): {},", farmer_key);
info!("\tPoolPublicKey(OG Plots): {},", pool_key);
info!("\tPlotNfts(NFT Plots): {{");
let total = plotnfts.len();
for (index, plot_nft) in plotnfts.into_iter().enumerate() {
info!("\t {{");
info!("\t LauncherID: {},", plot_nft.launcher_id);
info!(
"\t ContractAddress: {}",
encode_puzzle_hash(
&launcher_id_to_p2_puzzle_hash(
&plot_nft.launcher_id,
plot_nft.delay_time as u64,
&plot_nft.delay_puzzle_hash,
)?,
"xch"
)?
);
info!("\t }}{}", if index != total - 1 { "," } else { "" });
}
info!("\t}}");
info!("}}");
}
RootCommands::GetBlockchainState => {
let client = FullnodeClient::new(&host, port, timeout, ssl, &None);
let results = client.get_blockchain_state().await?;
Expand Down Expand Up @@ -426,7 +505,7 @@ async fn main() -> Result<(), Error> {
let mut cur = Cursor::new(
decode(s).expect("String is not valid SpendBundle Hex"),
);
SpendBundle::from_bytes(&mut cur)
SpendBundle::from_bytes(&mut cur, ChiaProtocolVersion::default())
.expect("String is not valid SpendBundle Hex")
} else {
serde_json::from_str(&s).expect("String is not a valid SpendBundle")
Expand Down
20 changes: 9 additions & 11 deletions cli/src/wallets/memory_wallet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,12 +208,14 @@ impl WalletStore for MemoryWalletStore {
}
None => {
let mut smaller_coin_sum = 0; //coins smaller than target.
let mut all_sum = 0; //coins smaller than target.
let mut smaller_coins = vec![];
for coin in &valid_spendable_coins {
if coin.amount < amount {
smaller_coin_sum += coin.amount;
smaller_coins.push(coin.clone());
}
smaller_coins.push(coin.clone());
all_sum += coin.amount;
}
if smaller_coin_sum == amount
&& smaller_coins.len() < max_num_coins
Expand All @@ -228,7 +230,7 @@ impl WalletStore for MemoryWalletStore {
debug!("Selected closest greater coin: {}", smallest_coin.name());
Ok(HashSet::from([smallest_coin]))
} else {
return Err(Error::new(ErrorKind::InvalidInput, "Transaction of {amount} mojo would use more than {max_num_coins} coins. Try sending a smaller amount"));
return Err(Error::new(ErrorKind::InvalidInput, format!("Transaction of {amount} mojo is greater than available sum {all_sum} mojos.")));
}
} else if smaller_coin_sum > amount {
let mut coin_set = knapsack_coin_algorithm(
Expand All @@ -252,7 +254,7 @@ impl WalletStore for MemoryWalletStore {
if let Some(greater_coin) = greater_coin {
coin_set = Some(HashSet::from([greater_coin]));
} else {
return Err(Error::new(ErrorKind::InvalidInput, "Transaction of {amount} mojo would use more than {max_num_coins} coins. Try sending a smaller amount"));
return Err(Error::new(ErrorKind::InvalidInput, format!("Transaction of {amount} mojo would use more than {max_num_coins} coins. Try sending a smaller amount")));
}
}
}
Expand Down Expand Up @@ -350,16 +352,12 @@ fn check_for_exact_match(coin_list: &[Coin], target: u64) -> Option<Coin> {
}

fn select_smallest_coin_over_target(target: u64, sorted_coin_list: &[Coin]) -> Option<Coin> {
if sorted_coin_list[0].amount < target {
None
} else {
for coin in sorted_coin_list.iter().rev() {
if coin.amount >= target {
return Some(coin.clone());
}
for coin in sorted_coin_list.iter() {
if coin.amount >= target {
return Some(coin.clone());
}
None
}
None
}

fn sum_largest_coins(target: u128, sorted_coins: &[Coin]) -> Option<HashSet<Coin>> {
Expand Down
4 changes: 2 additions & 2 deletions cli/src/wallets/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use dg_xch_puzzles::utils::{
make_assert_puzzle_announcement, make_create_coin_announcement, make_create_coin_condition,
make_create_puzzle_announcement, make_reserve_fee_condition,
};
use dg_xch_serialize::{hash_256, ChiaSerialize};
use dg_xch_serialize::{hash_256, ChiaProtocolVersion, ChiaSerialize};
use log::{debug, info};
use num_traits::ToPrimitive;
use std::cmp::max;
Expand Down Expand Up @@ -536,7 +536,7 @@ pub trait Wallet<T: WalletStore + Send + Sync, C> {
);
}
let message = hash_256(message_list.iter().fold(vec![], |mut v, e| {
v.extend(e.to_bytes());
v.extend(e.to_bytes(ChiaProtocolVersion::default()));
v
}));
let coin_announcements = HashSet::from([message.clone()]);
Expand Down
12 changes: 6 additions & 6 deletions clients/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "dg_xch_clients"
version = "2.0.2"
version = "2.0.3"
edition = "2021"
authors = ["James Hoerr"]
description = "RPC and Websocket Clients the Chia Blockchain"
Expand All @@ -12,11 +12,11 @@ repository = "https://github.com/GalactechsLLC/dg_xch_utils"
async-trait = "0.1.77"
blst = "0.3.11"
dashmap = "5.5.3"
dg_xch_core = {path = "../core", version = "2.0.2", default-features = false}
dg_xch_keys = {path = "../keys", version="2.0.2"}
dg_xch_macros = {path = "../macros", version="2.0.2"}
dg_xch_pos = {path = "../proof_of_space", version="2.0.2"}
dg_xch_serialize = {path = "../serialize", version="2.0.2"}
dg_xch_core = {path = "../core", version = "2.0.3", default-features = false}
dg_xch_keys = {path = "../keys", version="2.0.3"}
dg_xch_macros = {path = "../macros", version="2.0.3"}
dg_xch_pos = {path = "../proof_of_space", version="2.0.3"}
dg_xch_serialize = {path = "../serialize", version="2.0.3"}
futures-util = "0.3.30"
hex = "0.4.3"
hyper = {version="1.1.0", features=["full"]}
Expand Down
4 changes: 2 additions & 2 deletions clients/src/api/pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use dg_xch_core::protocols::pool::{
GetPoolInfoResponse, PoolError, PoolErrorCode, PostFarmerRequest, PostFarmerResponse,
PostPartialRequest, PostPartialResponse, PutFarmerRequest, PutFarmerResponse,
};
use dg_xch_serialize::{hash_256, ChiaSerialize};
use dg_xch_serialize::{hash_256, ChiaProtocolVersion, ChiaSerialize};
use log::warn;
use reqwest::{Client, RequestBuilder};
use serde::de::DeserializeOwned;
Expand Down Expand Up @@ -243,7 +243,7 @@ pub async fn create_pool_login_parts(
target_puzzle_hash: pool_info.target_puzzle_hash,
authentication_token: current_auth_token,
};
let to_sign = hash_256(payload.to_bytes());
let to_sign = hash_256(payload.to_bytes(ChiaProtocolVersion::default()));
let sig = sign(sec_key, &to_sign);
sigs.push(sig);
}
Expand Down
5 changes: 3 additions & 2 deletions clients/src/websocket/farmer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@ impl<T> FarmerClient<T> {
) -> Result<Self, Error> {
let constants = CONSENSUS_CONSTANTS_MAP
.get(&client_config.network_id)
.unwrap_or(&MAINNET);
.cloned()
.unwrap_or(MAINNET.clone());
let handles = Arc::new(RwLock::new(handles(constants, shared_state.clone())));
let client = WsClient::new(client_config, NodeType::Farmer, handles, run).await?;
Ok(FarmerClient {
Expand All @@ -48,7 +49,7 @@ impl<T> FarmerClient<T> {
}

fn handles<T>(
constants: &'static ConsensusConstants,
constants: Arc<ConsensusConstants>,
shared_state: Arc<FarmerSharedState<T>>,
) -> HashMap<Uuid, Arc<ChiaMessageHandler>> {
HashMap::from([
Expand Down
Loading

0 comments on commit 86a6640

Please sign in to comment.