Просмотр исходного кода

consensus: Deploy native money contract on startup.

parazyd 3 лет назад
Родитель
Сommit
fe611fbbcd
4 измененных файлов с 45 добавлено и 12 удалено
  1. 2 1
      Cargo.toml
  2. 4 1
      Makefile
  3. 29 1
      src/consensus/state.rs
  4. 10 9
      src/runtime/import/db.rs

+ 2 - 1
Cargo.toml

@@ -160,6 +160,7 @@ async-runtime = [
 blockchain = [
 blockchain = [
     "blake3",
     "blake3",
     "chrono",
     "chrono",
+    "dashu",
     "halo2_gadgets",
     "halo2_gadgets",
     "halo2_proofs",
     "halo2_proofs",
     "incrementalmerkletree",
     "incrementalmerkletree",
@@ -178,7 +179,7 @@ blockchain = [
     "tx",
     "tx",
     "node",
     "node",
     "util",
     "util",
-    "dep:dashu",
+    "wasm-runtime",
 ]
 ]
 
 
 crypto = [
 crypto = [

+ 4 - 1
Makefile

@@ -32,6 +32,9 @@ PROOFS_BIN = $(PROOFS:=.bin)
 
 
 all: zkas $(PROOFS_BIN) $(BINS)
 all: zkas $(PROOFS_BIN) $(BINS)
 
 
+contracts: zkas
+	$(MAKE) -C src/contract/money
+
 zkas: $(BINDEPS)
 zkas: $(BINDEPS)
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	cp -f target/release/$@ $@
 	cp -f target/release/$@ $@
@@ -42,7 +45,7 @@ $(PROOFS_BIN): $(PROOFS) zkas
 token_lists:
 token_lists:
 	$(MAKE) -C contrib/token all
 	$(MAKE) -C contrib/token all
 
 
-$(BINS): token_lists $(BINDEPS)
+$(BINS): token_lists contracts $(BINDEPS)
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	RUSTFLAGS="$(RUSTFLAGS)" $(CARGO) build --all-features --release --package $@
 	cp -f target/release/$@ $@
 	cp -f target/release/$@ $@
 
 

+ 29 - 1
src/consensus/state.rs

@@ -28,7 +28,7 @@ use chrono::{NaiveDateTime, Utc};
 use darkfi_sdk::crypto::{
 use darkfi_sdk::crypto::{
     constants::MERKLE_DEPTH,
     constants::MERKLE_DEPTH,
     schnorr::{SchnorrPublic, SchnorrSecret},
     schnorr::{SchnorrPublic, SchnorrSecret},
-    Address, MerkleNode, PublicKey, SecretKey,
+    Address, ContractId, MerkleNode, PublicKey, SecretKey,
 };
 };
 use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
 use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
 use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
@@ -54,6 +54,7 @@ use crate::{
         state::{state_transition, ProgramState, StateUpdate},
         state::{state_transition, ProgramState, StateUpdate},
         Client, MemoryState, State,
         Client, MemoryState, State,
     },
     },
+    runtime::vm_runtime::Runtime,
     tx::Transaction,
     tx::Transaction,
     util::time::Timestamp,
     util::time::Timestamp,
     zk::circuit::LeadContract,
     zk::circuit::LeadContract,
@@ -171,6 +172,33 @@ impl ValidatorState {
         let unconfirmed_txs = vec![];
         let unconfirmed_txs = vec![];
         let participating = None;
         let participating = None;
 
 
+        // -----BEGIN ARTIFACT: WASM INTEGRATION-----
+        // This is the current place where this stuff is being done, and very loosely.
+        // We initialize and "deploy" _native_ contracts here - currently the money contract.
+        // Eventually, the crypsinous consensus should be a native contract like payments are.
+        // This means the previously existing Blockchain state will be a bit different and is
+        // going to have to be changed.
+        // When the `Blockchain` object is created, it doesn't care whether it already has
+        // data or not. If there's existing data it will just open the necessary db and trees,
+        // and give back what it has. This means, on subsequent runs our native contracts will
+        // already be in a deployed state. So what we do here is a "re-deployment". This kind
+        // of operation should only modify the contract's state in case it wasn't deployed
+        // before (meaning the initial run). Otherwise, it shouldn't touch anything, or just
+        // potentially update the database schemas or whatever is necessary. Here it's
+        // transparent and generic, and the entire logic for this db protection is supposed to
+        // be in the `init` function of the contract, so look there for a reference of the
+        // databases and the state.
+        info!("ValidatorState::new(): Deploying \"money contract\"");
+        let money_contract_wasm_bincode = include_bytes!("../contract/money/money_contract.wasm");
+        // XXX: FIXME: This ID should be something that does not solve the pallas curve equation,
+        //             and/or just hardcoded and forbidden in non-native contract deployment.
+        let cid = ContractId::from(pallas::Base::from(u64::MAX - 420));
+        let mut runtime = Runtime::new(&money_contract_wasm_bincode[..], blockchain.clone(), cid)?;
+        runtime.deploy(&[])?;
+        info!("Deployed Money Contract with ID: {}", cid);
+
+        // -----END ARTIFACT-----
+
         let address = client.wallet.get_default_address().await?;
         let address = client.wallet.get_default_address().await?;
         let state_machine = Arc::new(Mutex::new(State {
         let state_machine = Arc::new(Mutex::new(State {
             tree: client.get_tree().await?,
             tree: client.get_tree().await?,

+ 10 - 9
src/runtime/import/db.rs

@@ -54,7 +54,7 @@ impl DbHandle {
     }
     }
 
 
     pub fn contains_key(&self, key: &[u8]) -> Result<bool> {
     pub fn contains_key(&self, key: &[u8]) -> Result<bool> {
-        self.tree.contains_key(key)
+        Ok(self.tree.contains_key(key)?)
     }
     }
 
 
     pub fn apply_batch(&self, batch: sled::Batch) -> Result<()> {
     pub fn apply_batch(&self, batch: sled::Batch) -> Result<()> {
@@ -94,7 +94,7 @@ pub(crate) fn db_init(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i
                 Ok(v) => v,
                 Ok(v) => v,
                 Err(e) => {
                 Err(e) => {
                     error!(target: "wasm_runtime::db_init", "Failed to decode ContractId: {}", e);
                     error!(target: "wasm_runtime::db_init", "Failed to decode ContractId: {}", e);
-                    return DN_INIT_FAILED
+                    return DB_INIT_FAILED
                 }
                 }
             };
             };
 
 
@@ -292,13 +292,13 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
 
 
             let Ok(mem_slice) = ptr.slice(&memory_view, len) else {
             let Ok(mem_slice) = ptr.slice(&memory_view, len) else {
                 error!(target: "wasm_runtime::db_get", "Failed to make slice from ptr");
                 error!(target: "wasm_runtime::db_get", "Failed to make slice from ptr");
-                return DB_GET_FAILED
+                return DB_GET_FAILED.into()
             };
             };
 
 
             let mut buf = vec![0_u8; len as usize];
             let mut buf = vec![0_u8; len as usize];
             if let Err(e) = mem_slice.read_slice(&mut buf) {
             if let Err(e) = mem_slice.read_slice(&mut buf) {
                 error!(target: "wasm_runtime::db_get", "Failed to read from memory slice: {}", e);
                 error!(target: "wasm_runtime::db_get", "Failed to read from memory slice: {}", e);
-                return DB_GET_FAILED
+                return DB_GET_FAILED.into()
             };
             };
 
 
             let mut buf_reader = Cursor::new(buf);
             let mut buf_reader = Cursor::new(buf);
@@ -308,7 +308,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
                 Ok(v) => v,
                 Ok(v) => v,
                 Err(e) => {
                 Err(e) => {
                     error!(target: "wasm_runtime::db_get", "Failed to decode DbHandle: {}", e);
                     error!(target: "wasm_runtime::db_get", "Failed to decode DbHandle: {}", e);
-                    return DB_GET_FAILED
+                    return DB_GET_FAILED.into()
                 }
                 }
             };
             };
             let db_handle = db_handle as usize;
             let db_handle = db_handle as usize;
@@ -317,7 +317,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
                 Ok(v) => v,
                 Ok(v) => v,
                 Err(e) => {
                 Err(e) => {
                     error!(target: "wasm_runtime::db_get", "Failed to decode key from vec: {}", e);
                     error!(target: "wasm_runtime::db_get", "Failed to decode key from vec: {}", e);
-                    return DB_GET_FAILED
+                    return DB_GET_FAILED.into()
                 }
                 }
             };
             };
 
 
@@ -327,7 +327,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
 
 
             if db_handles.len() <= db_handle {
             if db_handles.len() <= db_handle {
                 error!(target: "wasm_runtime::db_get", "Requested DbHandle that is out of bounds");
                 error!(target: "wasm_runtime::db_get", "Requested DbHandle that is out of bounds");
-                return DB_GET_FAILED
+                return DB_GET_FAILED.into()
             }
             }
 
 
             let handle_idx = db_handle;
             let handle_idx = db_handle;
@@ -337,7 +337,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
                 Ok(v) => v,
                 Ok(v) => v,
                 Err(e) => {
                 Err(e) => {
                     error!(target: "wasm_runtime::db_get", "Internal error getting from tree: {}", e);
                     error!(target: "wasm_runtime::db_get", "Internal error getting from tree: {}", e);
-                    return DB_GET_FAILED
+                    return DB_GET_FAILED.into()
                 }
                 }
             };
             };
 
 
@@ -351,7 +351,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
             objects.push(return_data);
             objects.push(return_data);
             (objects.len() - 1) as i64
             (objects.len() - 1) as i64
         }
         }
-        _ => CALLER_ACCESS_DENIED,
+        _ => CALLER_ACCESS_DENIED.into(),
     }
     }
 }
 }
 
 
@@ -422,5 +422,6 @@ pub(crate) fn db_contains_key(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u
                 }
                 }
             }
             }
         }
         }
+        _ => CALLER_ACCESS_DENIED,
     }
     }
 }
 }