Skip to content

Commit

Permalink
Add publish command and transaction types for Move module deployment
Browse files Browse the repository at this point in the history
  • Loading branch information
jamesatomc committed Dec 16, 2024
1 parent a61775e commit 031084f
Show file tree
Hide file tree
Showing 9 changed files with 214 additions and 36 deletions.
17 changes: 8 additions & 9 deletions crates/command/src/move_cli/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,7 @@ use move_package::BuildConfig;
use std::{path::PathBuf, process::exit};
use kari_move::{
base::{
build::Build,
coverage::{Coverage, CoverageSummaryOptions},
disassemble::Disassemble,
docgen::Docgen,
errmap::Errmap,
info::Info,
migrate::Migrate,
new::New,
test::Test,
build::Build, coverage::{Coverage, CoverageSummaryOptions}, disassemble::Disassemble, docgen::Docgen, errmap::Errmap, info::Info, migrate::Migrate, new::New, publish::Publish, test::Test
}, run_cli, sandbox, Command, Move
};

Expand All @@ -31,6 +23,7 @@ const COMMANDS: &[CommandInfo] = &[
CommandInfo { name: "info", description: "Print address information" },
CommandInfo { name: "new", description: "Create new Move package" },
CommandInfo { name: "test", description: "Run Move unit tests" },
CommandInfo { name: "publish", description: "Publish Move module" },
CommandInfo { name: "sandbox", description: "Execute sandbox commands" },
];

Expand Down Expand Up @@ -126,6 +119,12 @@ pub fn handle_move_command() {
compute_coverage: false,
gas_limit: None
}),
Some("publish") => Command::Publish(Publish {
module_path: PathBuf::new(),
gas_budget: 1000000,
address: None,
skip_verify: false
}),
Some("sandbox") => Command::Sandbox {
storage_dir: PathBuf::from(kari_move::DEFAULT_STORAGE_DIR),
cmd: sandbox::cli::SandboxCommand::Clean {}
Expand Down
33 changes: 27 additions & 6 deletions crates/core/k2/src/block/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

use serde::{Deserialize, Serialize};
use crate::{chain_id::CHAIN_ID, transaction::Transaction};
use crate::{chain_id::CHAIN_ID, gas::MOVE_MODULE_DEPLOY_GAS, transaction::Transaction};
use consensus_pos::HashAlgorithm;
use serde::{Deserialize, Serialize};

// Define the Block struct
#[derive(Serialize, Deserialize, Clone)]
Expand All @@ -21,8 +20,30 @@ pub struct Block<T: HashAlgorithm> {

// Implement the Block struct
impl<T: HashAlgorithm> Block<T> {
pub fn new(index: u32, data: Vec<u8>, prev_hash: String, tokens: u64, transactions: Vec<Transaction>, miner_address: String, hasher: T) -> Block<T> {
let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs();
// Add Move module deployment
pub fn deploy_move_module(&mut self, module_bytes: Vec<u8>, sender: String) {
self.data = module_bytes;
self.transactions.push(Transaction::new(
sender,
"system".to_string(),
MOVE_MODULE_DEPLOY_GAS as u64,
));
self.hash = self.calculate_hash();
}

pub fn new(
index: u32,
data: Vec<u8>,
prev_hash: String,
tokens: u64,
transactions: Vec<Transaction>,
miner_address: String,
hasher: T,
) -> Block<T> {
let timestamp = std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs();
let mut block = Block {
chain_id: CHAIN_ID.to_string(),
index,
Expand Down Expand Up @@ -50,7 +71,7 @@ impl<T: HashAlgorithm> Block<T> {
input.extend_from_slice(self.prev_hash.as_bytes());
input.extend_from_slice(&self.tokens.to_le_bytes());
input.extend_from_slice(self.token_name.as_bytes());

// Serialize transactions
let transactions_serialized = serde_json::to_string(&self.transactions).unwrap();
input.extend_from_slice(transactions_serialized.as_bytes());
Expand Down
54 changes: 37 additions & 17 deletions crates/core/k2/src/blockchain/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
// blockchain.rs
use crate::block::Block;
use bincode;
use consensus_pos::Blake3Algorithm;
use dirs;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::sync::Mutex;
use std::ptr::addr_of;
use std::fs;
use std::io::BufReader;
use std::path::PathBuf;
use dirs;
use bincode;
use consensus_pos::Blake3Algorithm;
use crate::block::Block;
use std::ptr::addr_of;
use std::sync::Mutex;

// Define global variables for the blockchain
pub static mut BALANCES: Option<Mutex<HashMap<String, u64>>> = None;
Expand All @@ -16,7 +18,17 @@ pub static mut TOTAL_TOKENS: u64 = 0;
// Define global variables for the blockchain
pub static mut BLOCKCHAIN: VecDeque<Block<Blake3Algorithm>> = VecDeque::new();

use std::io::BufReader;
// Add Move module storage
pub static mut MOVE_MODULES: Option<Mutex<HashMap<String, Vec<u8>>>> = None;

// Add Move module transaction type
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct MoveModuleTransaction {
pub sender: String,
pub module_bytes: Vec<u8>,
pub gas_cost: f64,
pub timestamp: u64,
}

pub fn get_kari_dir() -> PathBuf {
let mut path = dirs::home_dir().expect("Unable to find home directory");
Expand All @@ -31,23 +43,21 @@ pub fn save_blockchain() {
unsafe {
let data = bincode::serialize(addr_of!(BLOCKCHAIN).as_ref().unwrap())
.expect("Failed to serialize blockchain");
fs::write(&blockchain_file, data)
.expect("Unable to write blockchain to file");
fs::write(&blockchain_file, data).expect("Unable to write blockchain to file");
}
println!("Blockchain saved to {:?}", blockchain_file);
}

pub fn load_blockchain() {
let kari_dir = get_kari_dir();
let blockchain_file = kari_dir.join("data.log");

if blockchain_file.exists() {
unsafe {
// Use BufReader for faster reading
let file = fs::File::open(&blockchain_file)
.expect("Cannot open blockchain file");
let file = fs::File::open(&blockchain_file).expect("Cannot open blockchain file");
let reader = BufReader::new(file);

// Deserialize with better error handling
BLOCKCHAIN = match bincode::deserialize_from(reader) {
Ok(blockchain) => blockchain,
Expand All @@ -61,22 +71,32 @@ pub fn load_blockchain() {
let mut balances = HashMap::new();
let mut total_tokens = 0;

if MOVE_MODULES.is_none() {
MOVE_MODULES = Some(Mutex::new(HashMap::new()));
}

// Process blocks
for block in BLOCKCHAIN.iter() {
total_tokens += block.tokens;
*balances.entry(block.miner_address.clone()).or_insert(0) += block.tokens;

// Process transactions
for tx in &block.transactions {
*balances.entry(tx.sender.clone()).or_insert(0) -= tx.amount;
*balances.entry(tx.receiver.clone()).or_insert(0) += tx.amount;
}
}

if !block.data.is_empty() {
if let Ok(mut modules) = MOVE_MODULES.as_ref().unwrap().lock() {
modules.insert(block.hash.clone(), block.data.clone());
}
}
}

BALANCES = Some(Mutex::new(balances));
TOTAL_TOKENS = total_tokens;

println!("Blockchain loaded successfully from {:?}", blockchain_file);
}
}
}
}
6 changes: 5 additions & 1 deletion crates/core/k2/src/gas/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,8 @@ pub const DEPLOY_SM_TRANSACTION_GAS_COST: f64 = 0.00005000; // 0.00005000 KI
pub static mut TRANSACTION_SENDER: Option<Sender<Transaction>> = None; // Change to Option<Sender<Transaction>>
pub const MINT_NFT_TRANSACTION_GAS_COST: f64 = 0.00010000; // 0.00010000 KI
pub const TRANSFER_NFT_TRANSACTION_GAS_COST: f64 = 0.00000100; // 0.00000100 KI
pub const PAYMENT_TRANSACTION_GAS_COST: f64 = 0.00020000; // 0.00020000 KI
pub const PAYMENT_TRANSACTION_GAS_COST: f64 = 0.00020000; // 0.00020000 KI

// Add Move operation gas costs
pub const MOVE_MODULE_DEPLOY_GAS: f64 = 0.00050000; // 0.0005 KI
pub const MOVE_FUNCTION_CALL_GAS: f64 = 0.00001000; // 0.00001 KI
62 changes: 60 additions & 2 deletions crates/core/k2/src/transaction/mod.rs
Original file line number Diff line number Diff line change
@@ -1,16 +1,33 @@
use crate::gas::TRANSACTION_GAS_COST;
use crate::gas::{
TRANSACTION_GAS_COST,
MOVE_MODULE_DEPLOY_GAS,
MOVE_FUNCTION_CALL_GAS
};
use serde::{Serialize, Deserialize};
use secp256k1::{Secp256k1, Message, SecretKey};
use sha2::{Sha256, Digest};


#[derive(Debug, Serialize, Deserialize, Clone)]
pub enum TransactionType {
Transfer,
MoveModuleDeploy(Vec<u8>),
MoveFunctionCall {
module_id: String,
function: String,
args: Vec<String>
}
}

#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Transaction {
pub sender: String,
pub receiver: String,
pub amount: u64,
pub gas_cost: f64,
pub timestamp: u64,
pub signature: Option<String>, // Add signature field
pub signature: Option<String>,
pub tx_type: TransactionType, // Add transaction type
}

impl Transaction {
Expand All @@ -25,6 +42,7 @@ impl Transaction {
.unwrap()
.as_secs(),
signature: None,
tx_type: TransactionType::Transfer,
}
}

Expand Down Expand Up @@ -63,6 +81,46 @@ impl Transaction {
hash.copy_from_slice(&result);
hash
}

pub fn new_move_deploy(sender: String, module_bytes: Vec<u8>) -> Self {
Self {
sender,
receiver: "system".to_string(),
amount: 0,
gas_cost: MOVE_MODULE_DEPLOY_GAS,
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
signature: None,
tx_type: TransactionType::MoveModuleDeploy(module_bytes),
}
}

pub fn new_move_call(
sender: String,
module_id: String,
function: String,
args: Vec<String>
) -> Self {
Self {
sender,
receiver: module_id.clone(),
amount: 0,
gas_cost: MOVE_FUNCTION_CALL_GAS,
timestamp: std::time::SystemTime::now()
.duration_since(std::time::UNIX_EPOCH)
.unwrap()
.as_secs(),
signature: None,
tx_type: TransactionType::MoveFunctionCall {
module_id,
function,
args
},
}
}

}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions crates/kari-move/src/base/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ pub mod info;
pub mod migrate;
pub mod new;
pub mod test;
pub mod publish;

use move_package::source_package::layout::SourcePackageLayout;
use std::path::PathBuf;
Expand Down
72 changes: 72 additions & 0 deletions crates/kari-move/src/base/publish.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use anyhow::Result;
use clap::Parser;
use move_package::{
compilation::compiled_package::CompiledPackage,
BuildConfig
};
use move_vm_test_utils::gas_schedule::CostTable;
use std::path::PathBuf;
use crate::sandbox::{
utils::on_disk_state_view::OnDiskStateView,
commands::publish::publish,
};
use crate::DEFAULT_STORAGE_DIR;

#[derive(Parser)]
pub struct Publish {
/// Path to Move module
#[clap(long)]
pub module_path: PathBuf,

/// Gas budget for deployment
#[clap(long, default_value = "1000000")]
pub gas_budget: u64,

/// Module address
#[clap(long)]
pub address: Option<String>,

/// Skip verification
#[clap(long)]
pub skip_verify: bool,
}

impl Publish {
pub fn execute(
self,
path: Option<PathBuf>,
config: BuildConfig,
cost_table: &CostTable,
) -> Result<()> {
let package_path = path.unwrap_or_else(|| self.module_path.clone());
let storage_path = package_path.join(DEFAULT_STORAGE_DIR);

let state = OnDiskStateView::create(&package_path, &storage_path)?;
let package = compile_package(&package_path, config)?;

publish(
vec![], // natives
cost_table,
&state,
&package,
self.skip_verify,
true, // with_deps
true, // bundle
None, // override_ordering
false, // verbose
)
}
}

fn compile_package(
path: &PathBuf,
config: BuildConfig,
) -> Result<CompiledPackage> {
let build_config = BuildConfig {
install_dir: Some(path.clone()),
additional_named_addresses: config.additional_named_addresses,
..BuildConfig::default()
};

build_config.compile_package(path, &mut Vec::new())
}
2 changes: 2 additions & 0 deletions crates/kari-move/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub enum Command {
Migrate(Migrate),
New(New),
Test(Test),
Publish(base::publish::Publish),
/// Execute a sandbox command.
#[clap(name = "sandbox")]
Sandbox {
Expand Down Expand Up @@ -104,6 +105,7 @@ pub fn run_cli(
natives,
Some(cost_table.clone()),
),
Command::Publish(c) => c.execute(move_args.package_path, move_args.build_config, cost_table),
Command::Sandbox { storage_dir, cmd } => cmd.handle_command(
natives,
cost_table,
Expand Down
Loading

0 comments on commit 031084f

Please sign in to comment.