consensus: Deploy native money contract on startup.

This commit is contained in:
parazyd
2022-11-15 19:33:10 +01:00
parent 8a60502a2f
commit fe611fbbcd
4 changed files with 45 additions and 12 deletions

View File

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

View File

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

View File

@@ -28,7 +28,7 @@ use chrono::{NaiveDateTime, Utc};
use darkfi_sdk::crypto::{
constants::MERKLE_DEPTH,
schnorr::{SchnorrPublic, SchnorrSecret},
Address, MerkleNode, PublicKey, SecretKey,
Address, ContractId, MerkleNode, PublicKey, SecretKey,
};
use darkfi_serial::{serialize, SerialDecodable, SerialEncodable};
use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
@@ -54,6 +54,7 @@ use crate::{
state::{state_transition, ProgramState, StateUpdate},
Client, MemoryState, State,
},
runtime::vm_runtime::Runtime,
tx::Transaction,
util::time::Timestamp,
zk::circuit::LeadContract,
@@ -171,6 +172,33 @@ impl ValidatorState {
let unconfirmed_txs = vec![];
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 state_machine = Arc::new(Mutex::new(State {
tree: client.get_tree().await?,

View File

@@ -54,7 +54,7 @@ impl DbHandle {
}
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<()> {
@@ -94,7 +94,7 @@ pub(crate) fn db_init(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i
Ok(v) => v,
Err(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 {
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];
if let Err(e) = mem_slice.read_slice(&mut buf) {
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);
@@ -308,7 +308,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
Ok(v) => v,
Err(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;
@@ -317,7 +317,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
Ok(v) => v,
Err(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 {
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;
@@ -337,7 +337,7 @@ pub(crate) fn db_get(ctx: FunctionEnvMut<Env>, ptr: WasmPtr<u8>, len: u32) -> i6
Ok(v) => v,
Err(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.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,
}
}