mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 14:48:08 -05:00
script/research/gg: added a Makefile and use smol instead of async-std
This commit is contained in:
1
script/research/gg/.gitignore
vendored
1
script/research/gg/.gitignore
vendored
@@ -1,4 +1,5 @@
|
||||
/target
|
||||
Cargo.lock
|
||||
rustfmt.toml
|
||||
gg
|
||||
/genesis_txs
|
||||
|
||||
@@ -21,10 +21,10 @@ darkfi-sdk = {path = "../../../src/sdk"}
|
||||
darkfi-serial = "0.4.2"
|
||||
|
||||
# Misc
|
||||
async-std = {version = "1.13.0", features = ["attributes"]}
|
||||
bs58 = "0.5.1"
|
||||
clap = {version = "4.4.11", features = ["derive"]}
|
||||
sled-overlay = "0.1.6"
|
||||
smol = "2.0.2"
|
||||
|
||||
[patch.crates-io]
|
||||
halo2_proofs = {git="https://github.com/parazyd/halo2", branch="v4"}
|
||||
|
||||
37
script/research/gg/Makefile
Normal file
37
script/research/gg/Makefile
Normal file
@@ -0,0 +1,37 @@
|
||||
.POSIX:
|
||||
|
||||
# Install prefix
|
||||
PREFIX = $(HOME)/.cargo
|
||||
|
||||
# Cargo binary
|
||||
CARGO = cargo +nightly
|
||||
|
||||
# Compile target
|
||||
RUST_TARGET = $(shell rustc -Vv | grep '^host: ' | cut -d' ' -f2)
|
||||
# Uncomment when doing musl static builds
|
||||
#RUSTFLAGS = -C target-feature=+crt-static -C link-self-contained=yes
|
||||
|
||||
SRC = \
|
||||
Cargo.toml \
|
||||
$(shell find src -type f -name '*.rs') \
|
||||
|
||||
BIN = $(shell grep '^name = ' Cargo.toml | cut -d' ' -f3 | tr -d '"')
|
||||
|
||||
all: $(BIN)
|
||||
|
||||
$(BIN): $(SRC)
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --target=$(RUST_TARGET) --release --package $@
|
||||
cp -f target/$(RUST_TARGET)/release/$@ $@
|
||||
|
||||
fmt:
|
||||
$(CARGO) fmt --all
|
||||
|
||||
clippy:
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clippy --target=$(RUST_TARGET) \
|
||||
--release --all-features --workspace --tests
|
||||
|
||||
clean:
|
||||
RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) clean --target=$(RUST_TARGET) --release --package $(BIN)
|
||||
rm -f $(BIN)
|
||||
|
||||
.PHONY: all fmt clippy clean
|
||||
@@ -21,6 +21,7 @@ use std::{
|
||||
io::{stdin, Cursor, Read},
|
||||
process::exit,
|
||||
str::FromStr,
|
||||
sync::Arc,
|
||||
};
|
||||
|
||||
use clap::{Parser, Subcommand};
|
||||
@@ -45,6 +46,7 @@ use darkfi_sdk::{
|
||||
};
|
||||
use darkfi_serial::{deserialize_async, serialize_async, AsyncEncodable};
|
||||
use sled_overlay::sled;
|
||||
use smol::Executor;
|
||||
|
||||
#[derive(Parser)]
|
||||
#[command(about = cli_desc!())]
|
||||
@@ -102,174 +104,179 @@ async fn read_block() -> Result<BlockInfo> {
|
||||
Ok(block)
|
||||
}
|
||||
|
||||
#[async_std::main]
|
||||
async fn main() -> Result<()> {
|
||||
// Parse arguments
|
||||
let args = Args::parse();
|
||||
fn main() -> Result<()> {
|
||||
// Initialize an executor
|
||||
let executor = Arc::new(Executor::new());
|
||||
smol::block_on(executor.run(async {
|
||||
// Parse arguments
|
||||
let args = Args::parse();
|
||||
|
||||
// Execute a subcommand
|
||||
match args.command {
|
||||
Subcmd::Display => {
|
||||
let genesis_block = read_block().await;
|
||||
// TODO: display in more details
|
||||
println!("{genesis_block:?}");
|
||||
}
|
||||
|
||||
Subcmd::Generate { txs_folder, genesis_timestamp } => {
|
||||
// Grab genesis transactions from folder
|
||||
let txs_folder = expand_path(&txs_folder).unwrap();
|
||||
let mut genesis_txs: Vec<Transaction> = vec![];
|
||||
for file in read_dir(txs_folder)? {
|
||||
let file = file?;
|
||||
let bytes = base64::decode(read_to_string(file.path())?.trim()).unwrap();
|
||||
let tx = deserialize_async(&bytes).await?;
|
||||
genesis_txs.push(tx);
|
||||
// Execute a subcommand
|
||||
match args.command {
|
||||
Subcmd::Display => {
|
||||
let genesis_block = read_block().await;
|
||||
// TODO: display in more details
|
||||
println!("{genesis_block:?}");
|
||||
}
|
||||
|
||||
// Generate the genesis block
|
||||
let mut genesis_block = BlockInfo::default();
|
||||
|
||||
// Update timestamp if one was provided
|
||||
if let Some(timestamp) = genesis_timestamp {
|
||||
genesis_block.header.timestamp = Timestamp::from_u64(timestamp);
|
||||
}
|
||||
|
||||
// Retrieve genesis producer transaction
|
||||
let producer_tx = genesis_block.txs.pop().unwrap();
|
||||
|
||||
// Append genesis transactions
|
||||
if !genesis_txs.is_empty() {
|
||||
genesis_block.append_txs(genesis_txs);
|
||||
}
|
||||
genesis_block.append_txs(vec![producer_tx]);
|
||||
|
||||
// Write generated genesis block to stdin
|
||||
let encoded = base64::encode(&serialize_async(&genesis_block).await);
|
||||
println!("{encoded}");
|
||||
}
|
||||
|
||||
Subcmd::Verify => {
|
||||
let genesis_block = read_block().await?;
|
||||
let hash = genesis_block.hash();
|
||||
|
||||
println!("Verifying genesis block: {hash}");
|
||||
|
||||
// Initialize a temporary sled database
|
||||
let sled_db = sled::Config::new().temporary(true).open()?;
|
||||
let (_, vks) = vks::get_cached_pks_and_vks()?;
|
||||
vks::inject(&sled_db, &vks)?;
|
||||
|
||||
// Create an overlay over whole blockchain
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
let overlay = BlockchainOverlay::new(&blockchain)?;
|
||||
deploy_native_contracts(&overlay, 0).await?;
|
||||
|
||||
verify_genesis_block(&overlay, &genesis_block, 0).await?;
|
||||
|
||||
println!("Genesis block {hash} verified successfully!");
|
||||
}
|
||||
|
||||
Subcmd::GenerateTx { amounts, recipient, spend_hook, user_data } => {
|
||||
let mut buf = String::new();
|
||||
stdin().read_to_string(&mut buf)?;
|
||||
let signature_secret = SecretKey::from_str(buf.trim())?;
|
||||
|
||||
let mut coin_amounts = vec![];
|
||||
for amount in amounts {
|
||||
if let Err(e) = f64::from_str(&amount) {
|
||||
eprintln!("Invalid amount: {e:?}");
|
||||
exit(2);
|
||||
Subcmd::Generate { txs_folder, genesis_timestamp } => {
|
||||
// Grab genesis transactions from folder
|
||||
let txs_folder = expand_path(&txs_folder).unwrap();
|
||||
let mut genesis_txs: Vec<Transaction> = vec![];
|
||||
for file in read_dir(txs_folder)? {
|
||||
let file = file?;
|
||||
let bytes = base64::decode(read_to_string(file.path())?.trim()).unwrap();
|
||||
let tx = deserialize_async(&bytes).await?;
|
||||
genesis_txs.push(tx);
|
||||
}
|
||||
coin_amounts.push(decode_base10(&amount, 8, true)?);
|
||||
|
||||
// Generate the genesis block
|
||||
let mut genesis_block = BlockInfo::default();
|
||||
|
||||
// Update timestamp if one was provided
|
||||
if let Some(timestamp) = genesis_timestamp {
|
||||
genesis_block.header.timestamp = Timestamp::from_u64(timestamp);
|
||||
}
|
||||
|
||||
// Retrieve genesis producer transaction
|
||||
let producer_tx = genesis_block.txs.pop().unwrap();
|
||||
|
||||
// Append genesis transactions
|
||||
if !genesis_txs.is_empty() {
|
||||
genesis_block.append_txs(genesis_txs);
|
||||
}
|
||||
genesis_block.append_txs(vec![producer_tx]);
|
||||
|
||||
// Write generated genesis block to stdin
|
||||
let encoded = base64::encode(&serialize_async(&genesis_block).await);
|
||||
println!("{encoded}");
|
||||
}
|
||||
|
||||
let recipient = match recipient {
|
||||
Some(r) => match PublicKey::from_str(&r) {
|
||||
Ok(r) => Some(r),
|
||||
Err(e) => {
|
||||
eprintln!("Invalid recipient: {e:?}");
|
||||
Subcmd::Verify => {
|
||||
let genesis_block = read_block().await?;
|
||||
let hash = genesis_block.hash();
|
||||
|
||||
println!("Verifying genesis block: {hash}");
|
||||
|
||||
// Initialize a temporary sled database
|
||||
let sled_db = sled::Config::new().temporary(true).open()?;
|
||||
let (_, vks) = vks::get_cached_pks_and_vks()?;
|
||||
vks::inject(&sled_db, &vks)?;
|
||||
|
||||
// Create an overlay over whole blockchain
|
||||
let blockchain = Blockchain::new(&sled_db)?;
|
||||
let overlay = BlockchainOverlay::new(&blockchain)?;
|
||||
deploy_native_contracts(&overlay, 0).await?;
|
||||
|
||||
verify_genesis_block(&overlay, &genesis_block, 0).await?;
|
||||
|
||||
println!("Genesis block {hash} verified successfully!");
|
||||
}
|
||||
|
||||
Subcmd::GenerateTx { amounts, recipient, spend_hook, user_data } => {
|
||||
let mut buf = String::new();
|
||||
stdin().read_to_string(&mut buf)?;
|
||||
let signature_secret = SecretKey::from_str(buf.trim())?;
|
||||
|
||||
let mut coin_amounts = vec![];
|
||||
for amount in amounts {
|
||||
if let Err(e) = f64::from_str(&amount) {
|
||||
eprintln!("Invalid amount: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
coin_amounts.push(decode_base10(&amount, 8, true)?);
|
||||
}
|
||||
|
||||
let spend_hook = match spend_hook {
|
||||
Some(s) => match FuncId::from_str(&s) {
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
eprintln!("Invalid spend hook: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let user_data = match user_data {
|
||||
Some(u) => {
|
||||
let bytes: [u8; 32] = match bs58::decode(&u).into_vec()?.try_into() {
|
||||
Ok(b) => b,
|
||||
let recipient = match recipient {
|
||||
Some(r) => match PublicKey::from_str(&r) {
|
||||
Ok(r) => Some(r),
|
||||
Err(e) => {
|
||||
eprintln!("Invalid user data: {e:?}");
|
||||
eprintln!("Invalid recipient: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
};
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
match pallas::Base::from_repr(bytes).into() {
|
||||
Some(v) => Some(v),
|
||||
None => {
|
||||
eprintln!("Invalid user data");
|
||||
let spend_hook = match spend_hook {
|
||||
Some(s) => match FuncId::from_str(&s) {
|
||||
Ok(s) => Some(s),
|
||||
Err(e) => {
|
||||
eprintln!("Invalid spend hook: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let user_data = match user_data {
|
||||
Some(u) => {
|
||||
let bytes: [u8; 32] = match bs58::decode(&u).into_vec()?.try_into() {
|
||||
Ok(b) => b,
|
||||
Err(e) => {
|
||||
eprintln!("Invalid user data: {e:?}");
|
||||
exit(2);
|
||||
}
|
||||
};
|
||||
|
||||
match pallas::Base::from_repr(bytes).into() {
|
||||
Some(v) => Some(v),
|
||||
None => {
|
||||
eprintln!("Invalid user data");
|
||||
exit(2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
None => None,
|
||||
};
|
||||
|
||||
// Grab mint proving keys and zkbin
|
||||
let (pks, _) = vks::get_cached_pks_and_vks()?;
|
||||
let mut mint = None;
|
||||
for (bincode, namespace, pk) in pks {
|
||||
if namespace.as_str() != MONEY_CONTRACT_ZKAS_MINT_NS_V1 {
|
||||
continue
|
||||
// Grab mint proving keys and zkbin
|
||||
let (pks, _) = vks::get_cached_pks_and_vks()?;
|
||||
let mut mint = None;
|
||||
for (bincode, namespace, pk) in pks {
|
||||
if namespace.as_str() != MONEY_CONTRACT_ZKAS_MINT_NS_V1 {
|
||||
continue
|
||||
}
|
||||
let mut reader = Cursor::new(pk);
|
||||
let zkbin = ZkBinary::decode(&bincode)?;
|
||||
let circuit = ZkCircuit::new(empty_witnesses(&zkbin)?, &zkbin);
|
||||
let proving_key = ProvingKey::read(&mut reader, circuit)?;
|
||||
mint = Some((proving_key, zkbin));
|
||||
}
|
||||
let mut reader = Cursor::new(pk);
|
||||
let zkbin = ZkBinary::decode(&bincode)?;
|
||||
let circuit = ZkCircuit::new(empty_witnesses(&zkbin)?, &zkbin);
|
||||
let proving_key = ProvingKey::read(&mut reader, circuit)?;
|
||||
mint = Some((proving_key, zkbin));
|
||||
let Some((mint_pk, mint_zkbin)) = mint else {
|
||||
eprintln!("Mint proving keys not found.");
|
||||
exit(2);
|
||||
};
|
||||
|
||||
// Build the contract call
|
||||
let builder = GenesisMintCallBuilder {
|
||||
signature_public: PublicKey::from_secret(signature_secret),
|
||||
amounts: coin_amounts,
|
||||
recipient,
|
||||
spend_hook,
|
||||
user_data,
|
||||
mint_zkbin,
|
||||
mint_pk,
|
||||
};
|
||||
|
||||
let debris = builder.build()?;
|
||||
|
||||
// Encode and build the transaction
|
||||
let mut data = vec![MoneyFunction::GenesisMintV1 as u8];
|
||||
debris.params.encode_async(&mut data).await?;
|
||||
let call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data };
|
||||
let mut tx_builder = TransactionBuilder::new(
|
||||
ContractCallLeaf { call, proofs: debris.proofs },
|
||||
vec![],
|
||||
)?;
|
||||
let mut tx = tx_builder.build()?;
|
||||
let sigs = tx.create_sigs(&[signature_secret])?;
|
||||
tx.signatures = vec![sigs];
|
||||
|
||||
println!("{}", base64::encode(&serialize_async(&tx).await));
|
||||
}
|
||||
let Some((mint_pk, mint_zkbin)) = mint else {
|
||||
eprintln!("Mint proving keys not found.");
|
||||
exit(2);
|
||||
};
|
||||
|
||||
// Build the contract call
|
||||
let builder = GenesisMintCallBuilder {
|
||||
signature_public: PublicKey::from_secret(signature_secret),
|
||||
amounts: coin_amounts,
|
||||
recipient,
|
||||
spend_hook,
|
||||
user_data,
|
||||
mint_zkbin,
|
||||
mint_pk,
|
||||
};
|
||||
|
||||
let debris = builder.build()?;
|
||||
|
||||
// Encode and build the transaction
|
||||
let mut data = vec![MoneyFunction::GenesisMintV1 as u8];
|
||||
debris.params.encode_async(&mut data).await?;
|
||||
let call = ContractCall { contract_id: *MONEY_CONTRACT_ID, data };
|
||||
let mut tx_builder =
|
||||
TransactionBuilder::new(ContractCallLeaf { call, proofs: debris.proofs }, vec![])?;
|
||||
let mut tx = tx_builder.build()?;
|
||||
let sigs = tx.create_sigs(&[signature_secret])?;
|
||||
tx.signatures = vec![sigs];
|
||||
|
||||
println!("{}", base64::encode(&serialize_async(&tx).await));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
}))
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user