Skip to content

Commit

Permalink
First PlotNFT Moved, Lots of fixes and additions
Browse files Browse the repository at this point in the history
  • Loading branch information
luna committed Oct 18, 2023
1 parent 21bd701 commit cb93e18
Show file tree
Hide file tree
Showing 25 changed files with 774 additions and 403 deletions.
1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ num-traits = "0.2.17"
rand = "0.8.5"
rayon = "1.8.0"
serde = "1.0.189"
serde_json = "1.0.107"
simple_logger = "4.2.0"
tokio = {version = "1.33.0", features=["rt-multi-thread", "sync", "signal", "macros", "process", "time", "fs", "net"]}
7 changes: 6 additions & 1 deletion cli/src/cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ pub enum RootCommands {
#[arg(short, long)]
launcher_id: String,
#[arg(short, long)]
mnemonic: String
mnemonic: String,
},
#[command(about = "Gets plotnft state for launcher_id", long_about = None)]
GetPlotnftState {
#[arg(short, long)]
launcher_id: String
},
#[command(about = "Create a cold wallet or a PlotNFT wallet", long_about = None)]
CreateWallet {
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

28 changes: 22 additions & 6 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pub mod cli;
use clap::Parser;
use cli::*;
use dg_xch_cli::wallet_commands::{create_cold_wallet, get_plotnft_state, migrate_plot_nft};
use dg_xch_clients::rpc::full_node::FullnodeClient;
use simple_logger::SimpleLogger;
use std::io::Error;
use dg_xch_cli::wallet_commands::{create_cold_wallet, migrate_plot_nft};
use dg_xch_clients::rpc::full_node::FullnodeClient;

#[tokio::main]
async fn main() -> Result<(), Error> {
Expand All @@ -15,16 +15,32 @@ async fn main() -> Result<(), Error> {
RootCommands::GetCoinRecord { .. } => {
//Do Stuff Here
}
RootCommands::MovePlotNFT { target_pool, launcher_id, mnemonic } => {
RootCommands::MovePlotNFT {
target_pool,
launcher_id,
mnemonic,
} => {
let host = cli.fullnode_host.unwrap_or("localhost".to_string());
let client = FullnodeClient::new(
&host,
cli.fullnode_port.unwrap_or(8444),
cli.ssl_path,
&None
&None,
);
migrate_plot_nft(client, target_pool, launcher_id, mnemonic).await?
},
migrate_plot_nft(&client, &target_pool, &launcher_id, &mnemonic).await?
}
RootCommands::GetPlotnftState {
launcher_id,
} => {
let host = cli.fullnode_host.unwrap_or("localhost".to_string());
let client = FullnodeClient::new(
&host,
cli.fullnode_port.unwrap_or(8444),
cli.ssl_path,
&None,
);
get_plotnft_state(&client, &launcher_id).await?
}
RootCommands::CreateWallet { action } => match action {
WalletAction::WithNFT { .. } => {}
WalletAction::Cold => create_cold_wallet()?,
Expand Down
97 changes: 66 additions & 31 deletions cli/src/wallet_commands.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
use crate::wallets::memory_wallet::{MemoryWalletConfig, MemoryWalletStore};
use crate::wallets::plotnft_utils::{scrounge_for_plotnft_by_key, PlotNFTWallet, get_plotnft_by_launcher_id};
use crate::wallets::{Wallet, WalletInfo};
use bip39::Mnemonic;
use blst::min_pk::SecretKey;
use dg_xch_clients::api::pool::{DefaultPoolClient, PoolClient};
use dg_xch_clients::protocols::pool::{FARMING_TO_POOL, POOL_PROTOCOL_VERSION};
use dg_xch_clients::rpc::full_node::FullnodeClient;
use dg_xch_core::blockchain::coin_spend::CoinSpend;
use dg_xch_core::blockchain::sized_bytes::{Bytes32, Bytes48};
use dg_xch_core::blockchain::wallet_type::WalletType;
use dg_xch_core::consensus::constants::MAINNET;
use dg_xch_core::pool::PoolState;
use dg_xch_keys::*;
use dg_xch_puzzles::p2_delegated_puzzle_or_hidden_puzzle::{
calculate_synthetic_secret_key, puzzle_hash_for_pk, DEFAULT_HIDDEN_PUZZLE_HASH,
Expand All @@ -10,16 +19,10 @@ use log::{error, info};
use std::collections::{HashMap, HashSet};
use std::io::{Error, ErrorKind};
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::Mutex;
use crate::wallets::plotnft_utils::{PlotNFTWallet, scrounge_for_plotnft_by_key};
use crate::wallets::{Wallet, WalletInfo};
use crate::wallets::memory_wallet::{MemoryWalletConfig, MemoryWalletStore};
use dg_xch_clients::api::pool::{DefaultPoolClient, PoolClient};
use dg_xch_clients::protocols::pool::{FARMING_TO_POOL, POOL_PROTOCOL_VERSION};
use dg_xch_clients::rpc::full_node::FullnodeClient;
use dg_xch_core::blockchain::wallet_type::WalletType;
use dg_xch_core::consensus::constants::MAINNET;
use dg_xch_core::pool::PoolState;
use dg_xch_clients::api::full_node::FullnodeAPI;
use dg_xch_core::plots::PlotNft;

pub fn create_cold_wallet() -> Result<(), Error> {
let mnemonic = Mnemonic::generate(24)
Expand Down Expand Up @@ -96,10 +99,10 @@ pub fn keys_for_coinspends(
}

pub async fn migrate_plot_nft(
client: FullnodeClient,
target_pool: String,
launcher_id: String,
mnemonic: String,
client: &FullnodeClient,
target_pool: &str,
launcher_id: &str,
mnemonic: &str,
) -> Result<(), Error> {
let pool_client = DefaultPoolClient::new();
let master_secret_key = key_from_mnemonic(&mnemonic)?;
Expand All @@ -124,12 +127,15 @@ pub async fn migrate_plot_nft(
if pool_info.relative_lock_height > 1000 {
let error_message = "Relative lock height too high for this pool, cannot join";
error!("{}", error_message);
return Err(Error::new(ErrorKind::InvalidData, error_message))
return Err(Error::new(ErrorKind::InvalidData, error_message));
}
if pool_info.protocol_version != POOL_PROTOCOL_VERSION {
let error_message = format!("Incorrect version: {}, should be {POOL_PROTOCOL_VERSION}", pool_info.protocol_version);
let error_message = format!(
"Incorrect version: {}, should be {POOL_PROTOCOL_VERSION}",
pool_info.protocol_version
);
error!("{}", error_message);
return Err(Error::new(ErrorKind::InvalidData, error_message))
return Err(Error::new(ErrorKind::InvalidData, error_message));
}
let pool_wallet = PlotNFTWallet::create(
WalletInfo {
Expand All @@ -138,18 +144,15 @@ pub async fn migrate_plot_nft(
wallet_type: WalletType::PoolingWallet,
constants: Default::default(),
master_sk: master_secret_key.clone(),
wallet_store: Arc::new(Mutex::new(MemoryWalletStore::new(
master_secret_key,
0
))),
wallet_store: Arc::new(Mutex::new(MemoryWalletStore::new(master_secret_key, 0))),
data: "".to_string(),
},
MemoryWalletConfig {
fullnode_host: client.host.clone(),
fullnode_port: client.port,
fullnode_ssl_path: client.ssl_path.clone(),
additional_headers: client.additional_headers.clone(),
}
},
);
let launcher_to_find = Bytes32::from(launcher_id);
if !pool_wallet.sync().await? {
Expand All @@ -167,25 +170,57 @@ pub async fn migrate_plot_nft(
owner_pubkey: Bytes48::from_sized_bytes(owner_sk.sk_to_pk().to_bytes()),
pool_url: Some(pool_url.to_string()),
relative_lock_height: pool_info.relative_lock_height,
state: FARMING_TO_POOL, //# Farming to Pool
state: FARMING_TO_POOL, //# Farming to Pool
target_puzzle_hash: pool_info.target_puzzle_hash,
version: 1,
};
if plot_nft.pool_state == target_pool_state {
let error_message = format!("Current State equal to Target State: {:?}", &target_pool_state);
let error_message = format!(
"Current State equal to Target State: {:?}",
&target_pool_state
);
error!("{}", error_message);
return Err(Error::new(ErrorKind::InvalidData, error_message))
return Err(Error::new(ErrorKind::InvalidData, error_message));
}
let fee = 40;
let (travel_record, fee_record) = pool_wallet.generate_travel_transaction(
&plot_nft,
&target_pool_state,
fee,
&MAINNET
).await?;
let fee = 0;
let (travel_record, fee_record) = pool_wallet
.generate_travel_transaction(&plot_nft, target_pool_state, fee, &MAINNET)
.await?;
info!("{:?}", travel_record);
info!("{:?}", fee_record);
let coin_to_find = travel_record.additions.iter().find(|c| c.amount == 1).expect("Failed to find NFT coin");
let result = client.push_tx(&travel_record.spend_bundle.expect("Expected Transaction record to have Spend bundle")).await?;
info!("{:?}", result);
loop {
let record = client.get_coin_record_by_name(&coin_to_find.name()).await;
if let Ok(Some(record)) = record {
let parent = client.get_coin_record_by_name(&record.coin.parent_coin_info).await;
if let Ok(Some(record)) = parent {
info!("Found spent parent coin, Parent Coin was spent at {}", record.spent_block_index);
break;
}
}
tokio::time::sleep(Duration::from_secs(10)).await;
info!("Waiting for coin record for plotnft move to appear");
}
break;
}
Ok(())
}


pub async fn get_plotnft_state(
client: &FullnodeClient,
launcher_id: &str
) -> Result<(), Error> {
let launcher_to_find = Bytes32::from(launcher_id);
match get_plotnft_by_launcher_id(&client, &launcher_to_find).await? {
None => {
error!("Failed to find PlotNFT with LauncherID: {}", launcher_id);
}
Some(plotnft) => {
info!("Found PlotNFT: {}", serde_json::to_string_pretty(&plotnft).unwrap_or_default());
}
}
Ok(())
}
39 changes: 22 additions & 17 deletions cli/src/wallets/common.rs
Original file line number Diff line number Diff line change
@@ -1,42 +1,43 @@
use std::future::Future;
use blst::min_pk::{AggregateSignature, PublicKey, SecretKey, Signature};
use dg_xch_core::blockchain::coin_spend::{CoinSpend};
use dg_xch_core::blockchain::coin_spend::CoinSpend;
use dg_xch_core::blockchain::sized_bytes::{Bytes32, Bytes48, Bytes96, SizedBytes};
use dg_xch_core::blockchain::spend_bundle::SpendBundle;
use dg_xch_core::blockchain::utils::pkm_pairs_for_conditions_dict;
use dg_xch_core::blockchain::wallet_type::WalletType;
use dg_xch_core::clvm::bls_bindings;
use dg_xch_core::clvm::bls_bindings::{aggregate_verify_signature, verify_signature};
use dg_xch_core::clvm::condition_utils::conditions_dict_for_solution;
use dg_xch_core::consensus::constants::ConsensusConstants;
use num_traits::cast::ToPrimitive;
use std::future::Future;
use std::io::{Error, ErrorKind};
use dg_xch_core::blockchain::wallet_type::WalletType;
use log::info;

pub struct DerivationRecord {
pub index: u32,
pub puzzle_hash: Bytes32,
pub pubkey: Bytes48,
pub wallet_type: WalletType,
pub wallet_id: u32,
pub hardened: bool
pub hardened: bool,
}

pub async fn sign_coin_spend<F, Fut>(
coin_spend: CoinSpend,
key_fn: F,
constants: &ConsensusConstants,
) -> Result<SpendBundle, Error>
where
F: Fn(&Bytes48) -> Fut,
Fut: Future<Output = Result<SecretKey, Error>>
where
F: Fn(&Bytes48) -> Fut,
Fut: Future<Output = Result<SecretKey, Error>>,
{
sign_coin_spends(
vec![coin_spend],
key_fn,
&constants.agg_sig_me_additional_data,
constants.max_block_cost_clvm.to_u64().unwrap(),
)
.await
.await
}

pub async fn sign_coin_spends<F, Fut>(
Expand All @@ -45,9 +46,9 @@ pub async fn sign_coin_spends<F, Fut>(
additional_data: &[u8],
max_cost: u64,
) -> Result<SpendBundle, Error>
where
F: Fn(&Bytes48) -> Fut,
Fut: Future<Output = Result<SecretKey, Error>>
where
F: Fn(&Bytes48) -> Fut,
Fut: Future<Output = Result<SecretKey, Error>>,
{
let mut signatures: Vec<Signature> = vec![];
let mut pk_list: Vec<Bytes48> = vec![];
Expand All @@ -59,10 +60,10 @@ pub async fn sign_coin_spends<F, Fut>(
&coin_spend.solution,
max_cost,
)?
.0;
.0;
//Create signature
for (pk_bytes, msg) in
pkm_pairs_for_conditions_dict(conditions_dict, coin_spend.coin.name(), additional_data)?
pkm_pairs_for_conditions_dict(conditions_dict, coin_spend.coin.name(), additional_data)?
{
let pk = PublicKey::from_bytes(pk_bytes.as_slice()).map_err(|e| {
Error::new(
Expand All @@ -78,6 +79,9 @@ pub async fn sign_coin_spends<F, Fut>(
assert_eq!(&secret_key.sk_to_pk(), &pk);
let signature = bls_bindings::sign(&secret_key, &msg);
assert!(verify_signature(&pk, &msg, &signature));
info!("Sec Key: {}", hex::encode(secret_key.to_bytes().as_slice()));
info!("Msg Hex: {}", hex::encode(&msg));
info!("Sig Hex: {}", hex::encode(signature.to_bytes().as_slice()));
pk_list.push(pk_bytes);
msg_list.push(msg);
signatures.push(signature);
Expand All @@ -92,14 +96,15 @@ pub async fn sign_coin_spends<F, Fut>(
ErrorKind::Other,
format!("Failed to aggregate signatures: {:?}", e),
)
})?;
})?.to_signature();
info!("AggSig Hex: {}", hex::encode(aggsig.to_bytes().as_slice()));
assert!(aggregate_verify_signature(
&pk_list,
&msg_list,
&aggsig.to_signature()
&aggsig
));
Ok(SpendBundle {
coin_spends,
aggregated_signature: Bytes96::from(aggsig.to_signature()),
aggregated_signature: Bytes96::from(aggsig),
})
}
}
Loading

0 comments on commit cb93e18

Please sign in to comment.