diff --git a/src/blockchain/block_store.rs b/src/blockchain/block_store.rs index 133cc0c8b..730dae1ba 100644 --- a/src/blockchain/block_store.rs +++ b/src/blockchain/block_store.rs @@ -259,7 +259,7 @@ impl BlockOrderStore { ret.push(Some(hash)); } else { if strict { - return Err(Error::SlotNotFound(*slot)) + return Err(Error::BlockSlotNotFound(*slot)) } ret.push(None); } diff --git a/src/blockchain/mod.rs b/src/blockchain/mod.rs index 478267591..051b3e69e 100644 --- a/src/blockchain/mod.rs +++ b/src/blockchain/mod.rs @@ -20,7 +20,7 @@ use std::sync::{Arc, Mutex}; use log::debug; -use darkfi_sdk::blockchain::SlotCheckpoint; +use darkfi_sdk::blockchain::Slot; use darkfi_serial::serialize; use crate::{ @@ -33,8 +33,8 @@ use crate::{ pub mod block_store; pub use block_store::{BlockOrderStore, BlockStore, HeaderStore}; -pub mod slot_checkpoint_store; -pub use slot_checkpoint_store::{SlotCheckpointStore, SlotCheckpointStoreOverlay}; +pub mod slot_store; +pub use slot_store::{SlotStore, SlotStoreOverlay}; pub mod tx_store; pub use tx_store::{PendingTxOrderStore, PendingTxStore, TxStore}; @@ -55,8 +55,8 @@ pub struct Blockchain { pub blocks: BlockStore, /// Block order sled tree pub order: BlockOrderStore, - /// Slot checkpoints sled tree - pub slot_checkpoints: SlotCheckpointStore, + /// Slot sled tree + pub slots: SlotStore, /// Transactions sled tree pub transactions: TxStore, /// Pending transactions sled tree @@ -75,7 +75,7 @@ impl Blockchain { let headers = HeaderStore::new(db, genesis_ts, genesis_data)?; let blocks = BlockStore::new(db, genesis_ts, genesis_data)?; let order = BlockOrderStore::new(db, genesis_ts, genesis_data)?; - let slot_checkpoints = SlotCheckpointStore::new(db, genesis_data)?; + let slots = SlotStore::new(db, genesis_data)?; let transactions = TxStore::new(db)?; let pending_txs = PendingTxStore::new(db)?; let pending_txs_order = PendingTxOrderStore::new(db)?; @@ -87,7 +87,7 @@ impl Blockchain { headers, blocks, order, - slot_checkpoints, + slots, transactions, pending_txs, pending_txs_order, @@ -200,38 +200,35 @@ impl Blockchain { self.order.get_last() } - /// Retrieve the last slot checkpoint. - pub fn last_slot_checkpoint(&self) -> Result { - self.slot_checkpoints.get_last() + /// Retrieve the last slot. + pub fn last_slot(&self) -> Result { + self.slots.get_last() } - /// Retrieve n checkpoints after given start slot. - pub fn get_slot_checkpoints_after(&self, slot: u64, n: u64) -> Result> { - debug!(target: "blockchain", "get_slot_checkpoints_after(): {} -> {}", slot, n); - self.slot_checkpoints.get_after(slot, n) + /// Retrieve n slots after given start slot. + pub fn get_slots_after(&self, slot: u64, n: u64) -> Result> { + debug!(target: "blockchain", "get_slots_after(): {} -> {}", slot, n); + self.slots.get_after(slot, n) } - /// Insert a given slice of [`SlotCheckpoint`] into the blockchain database. - pub fn add_slot_checkpoints(&self, slot_checkpoints: &[SlotCheckpoint]) -> Result<()> { - self.slot_checkpoints.insert(slot_checkpoints) + /// Insert a given slice of [`Slot`] into the blockchain database. + pub fn add_slots(&self, slots: &[Slot]) -> Result<()> { + self.slots.insert(slots) } - /// Retrieve [`SlotCheckpoint`]s by given slots. Does not fail if any of them are not found. - pub fn get_slot_checkpoints_by_slot( - &self, - slots: &[u64], - ) -> Result>> { - debug!(target: "blockchain", "get_slot_checkpoints_by_slot(): {:?}", slots); - self.slot_checkpoints.get(slots, true) + /// Retrieve [`Slot`]s by given ids. Does not fail if any of them are not found. + pub fn get_slots_by_id(&self, ids: &[u64]) -> Result>> { + debug!(target: "blockchain", "get_slots_by_id(): {:?}", ids); + self.slots.get(ids, true) } - /// Check if the given [`SlotCheckpoint`] is in the database and all trees. - pub fn has_slot_checkpoint(&self, slot_checkpoint: &SlotCheckpoint) -> Result { - Ok(self.slot_checkpoints.get(&[slot_checkpoint.slot], true).is_ok()) + /// Check if the given [`Slot`] is in the database and all trees. + pub fn has_slot(&self, slot: &Slot) -> Result { + Ok(self.slots.get(&[slot.id], true).is_ok()) } /// Check if block order for the given slot is in the database. - pub fn has_slot(&self, slot: u64) -> Result { + pub fn has_slot_order(&self, slot: u64) -> Result { let vec = match self.order.get(&[slot], true) { Ok(v) => v, Err(_) => return Ok(false), @@ -299,8 +296,8 @@ pub type BlockchainOverlayPtr = Arc>; pub struct BlockchainOverlay { /// Main [`sled_overlay::SledDbOverlay`] to the sled db connection pub overlay: SledDbOverlayPtr, - /// Slot checkpoints overlay - pub slot_checkpoints: SlotCheckpointStoreOverlay, + /// Slots overlay + pub slots: SlotStoreOverlay, /// Contract states overlay pub contracts: ContractStateStoreOverlay, /// Wasm bincodes overlay @@ -311,11 +308,11 @@ impl BlockchainOverlay { /// Instantiate a new `BlockchainOverlay` over the given [`Blockchain`] instance. pub fn new(blockchain: &Blockchain) -> Result { let overlay = Arc::new(Mutex::new(sled_overlay::SledDbOverlay::new(&blockchain.sled_db))); - let slot_checkpoints = SlotCheckpointStoreOverlay::new(overlay.clone())?; + let slots = SlotStoreOverlay::new(overlay.clone())?; let contracts = ContractStateStoreOverlay::new(overlay.clone())?; let wasm_bincode = WasmStoreOverlay::new(overlay.clone())?; - Ok(Arc::new(Mutex::new(Self { overlay, slot_checkpoints, contracts, wasm_bincode }))) + Ok(Arc::new(Mutex::new(Self { overlay, slots, contracts, wasm_bincode }))) } /// Checkpoint overlay so we can revert to it, if needed. diff --git a/src/blockchain/slot_checkpoint_store.rs b/src/blockchain/slot_checkpoint_store.rs deleted file mode 100644 index 743adc59c..000000000 --- a/src/blockchain/slot_checkpoint_store.rs +++ /dev/null @@ -1,162 +0,0 @@ -/* This file is part of DarkFi (https://dark.fi) - * - * Copyright (C) 2020-2023 Dyne.org foundation - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -use darkfi_sdk::blockchain::SlotCheckpoint; -use darkfi_serial::{deserialize, serialize}; - -use crate::{blockchain::SledDbOverlayPtr, Error, Result}; - -const SLED_SLOT_CHECKPOINT_TREE: &[u8] = b"_slot_checkpoints"; - -/// The `SlotCheckpointStore` is a `sled` tree storing the checkpoints of the -/// blockchain's slots, where the key is the slot uid, and the value is -/// is the serialized checkpoint. -#[derive(Clone)] -pub struct SlotCheckpointStore(sled::Tree); - -impl SlotCheckpointStore { - /// Opens a new or existing `SlotCheckpointStore` on the given sled database. - pub fn new(db: &sled::Db, genesis_block: blake3::Hash) -> Result { - let tree = db.open_tree(SLED_SLOT_CHECKPOINT_TREE)?; - let store = Self(tree); - - // In case the store is empty, initialize it with the genesis checkpoint. - if store.0.is_empty() { - let genesis_checkpoint = SlotCheckpoint::genesis_slot_checkpoint(genesis_block); - store.insert(&[genesis_checkpoint])?; - } - - Ok(store) - } - - /// Insert a slice of [`SlotCheckpoint`] into the slotcheckpointstore. - /// With sled, the operation is done as a batch. - /// The block slot is used as the key, while value is the serialized [`SlotCheckpoint`] itself. - pub fn insert(&self, checkpoints: &[SlotCheckpoint]) -> Result<()> { - let mut batch = sled::Batch::default(); - - for checkpoint in checkpoints { - let serialized = serialize(checkpoint); - batch.insert(&checkpoint.slot.to_be_bytes(), serialized); - } - - self.0.apply_batch(batch)?; - Ok(()) - } - - /// Check if the slotcheckpointstore contains a given slot. - pub fn contains(&self, slot: u64) -> Result { - Ok(self.0.contains_key(slot.to_be_bytes())?) - } - - /// Fetch given slots from the slotcheckpointstore. - /// The resulting vector contains `Option`, which is `Some` if the slot - /// was found in the slotcheckpointstore, and otherwise it is `None`, if it has not. - /// The second parameter is a boolean which tells the function to fail in - /// case at least one slot was not found. - pub fn get(&self, slots: &[u64], strict: bool) -> Result>> { - let mut ret = Vec::with_capacity(slots.len()); - - for slot in slots { - if let Some(found) = self.0.get(slot.to_be_bytes())? { - let checkpoint = deserialize(&found)?; - ret.push(Some(checkpoint)); - } else { - if strict { - return Err(Error::SlotNotFound(*slot)) - } - ret.push(None); - } - } - - Ok(ret) - } - - /// Retrieve all slot checkpointss from the slotcheckpointstore. - /// Be careful as this will try to load everything in memory. - pub fn get_all(&self) -> Result> { - let mut slots = vec![]; - - for slot in self.0.iter() { - let (_, value) = slot.unwrap(); - let checkpoint = deserialize(&value)?; - slots.push(checkpoint); - } - - Ok(slots) - } - - /// Fetch n slot checkpoints after given slot. In the iteration, if a slot is not - /// found, the iteration stops and the function returns what it has found - /// so far in the `SlotCheckpointStore`. - pub fn get_after(&self, slot: u64, n: u64) -> Result> { - let mut ret = vec![]; - - let mut key = slot; - let mut counter = 0; - while counter <= n { - if let Some(found) = self.0.get_gt(key.to_be_bytes())? { - let key_bytes: [u8; 8] = found.0.as_ref().try_into().unwrap(); - key = u64::from_be_bytes(key_bytes); - let checkpoint = deserialize(&found.1)?; - ret.push(checkpoint); - counter += 1; - continue - } - break - } - - Ok(ret) - } - - /// Fetch the last slot checkpoint in the tree, based on the `Ord` - /// implementation for `Vec`. This should not be able to - /// fail because we initialize the store with the genesis slot checkpoint. - pub fn get_last(&self) -> Result { - let found = self.0.last()?.unwrap(); - let checkpoint = deserialize(&found.1)?; - Ok(checkpoint) - } - - /// Retrieve records count - pub fn len(&self) -> usize { - self.0.len() - } - - pub fn is_empty(&self) -> bool { - self.0.len() == 0 - } -} - -/// Overlay structure over a [`SlotCheckpointStore`] instance. -pub struct SlotCheckpointStoreOverlay(SledDbOverlayPtr); - -impl SlotCheckpointStoreOverlay { - pub fn new(overlay: SledDbOverlayPtr) -> Result { - overlay.lock().unwrap().open_tree(SLED_SLOT_CHECKPOINT_TREE)?; - Ok(Self(overlay)) - } - - /// Fetch given slot from the slotcheckpointstore. - pub fn get(&self, slot: u64) -> Result> { - match self.0.lock().unwrap().get(SLED_SLOT_CHECKPOINT_TREE, &slot.to_be_bytes())? { - Some(found) => Ok(found.to_vec()), - None => Err(Error::SlotNotFound(slot)), - } - } -} diff --git a/src/blockchain/slot_store.rs b/src/blockchain/slot_store.rs new file mode 100644 index 000000000..6f9a4f95d --- /dev/null +++ b/src/blockchain/slot_store.rs @@ -0,0 +1,161 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2023 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +use darkfi_sdk::blockchain::Slot; +use darkfi_serial::{deserialize, serialize}; + +use crate::{blockchain::SledDbOverlayPtr, Error, Result}; + +const SLED_SLOT_TREE: &[u8] = b"_slots"; + +/// The `SlotStore` is a `sled` tree storing the blockhains' slots, +/// where the key is the slot uid, and the value is is the serialized slot. +#[derive(Clone)] +pub struct SlotStore(sled::Tree); + +impl SlotStore { + /// Opens a new or existing `SlotStore` on the given sled database. + pub fn new(db: &sled::Db, genesis_block: blake3::Hash) -> Result { + let tree = db.open_tree(SLED_SLOT_TREE)?; + let store = Self(tree); + + // In case the store is empty, initialize it with the genesis slot. + if store.0.is_empty() { + let genesis_slot = Slot::genesis_slot(genesis_block); + store.insert(&[genesis_slot])?; + } + + Ok(store) + } + + /// Insert a slice of [`Slot`] into the slot store. + /// With sled, the operation is done as a batch. + /// The slot id is used as the key, while value is the serialized [`Slot`] itself. + pub fn insert(&self, slots: &[Slot]) -> Result<()> { + let mut batch = sled::Batch::default(); + + for slot in slots { + let serialized = serialize(slot); + batch.insert(&slot.id.to_be_bytes(), serialized); + } + + self.0.apply_batch(batch)?; + Ok(()) + } + + /// Check if the slot store contains a given id. + pub fn contains(&self, id: u64) -> Result { + Ok(self.0.contains_key(id.to_be_bytes())?) + } + + /// Fetch given slots from the slot store. + /// The resulting vector contains `Option`, which is `Some` if the slot + /// was found in the slot store, and otherwise it is `None`, if it has not. + /// The second parameter is a boolean which tells the function to fail in + /// case at least one slot was not found. + pub fn get(&self, ids: &[u64], strict: bool) -> Result>> { + let mut ret = Vec::with_capacity(ids.len()); + + for id in ids { + if let Some(found) = self.0.get(id.to_be_bytes())? { + let slot = deserialize(&found)?; + ret.push(Some(slot)); + } else { + if strict { + return Err(Error::SlotNotFound(*id)) + } + ret.push(None); + } + } + + Ok(ret) + } + + /// Retrieve all slot from the slot store. + /// Be careful as this will try to load everything in memory. + pub fn get_all(&self) -> Result> { + let mut slots = vec![]; + + for slot in self.0.iter() { + let (_, value) = slot.unwrap(); + let slot = deserialize(&value)?; + slots.push(slot); + } + + Ok(slots) + } + + /// Fetch n slots after given slot. In the iteration, if a slot is not + /// found, the iteration stops and the function returns what it has found + /// so far in the `SlotStore`. + pub fn get_after(&self, id: u64, n: u64) -> Result> { + let mut ret = vec![]; + + let mut key = id; + let mut counter = 0; + while counter <= n { + if let Some(found) = self.0.get_gt(key.to_be_bytes())? { + let key_bytes: [u8; 8] = found.0.as_ref().try_into().unwrap(); + key = u64::from_be_bytes(key_bytes); + let slot = deserialize(&found.1)?; + ret.push(slot); + counter += 1; + continue + } + break + } + + Ok(ret) + } + + /// Fetch the last slot in the tree, based on the `Ord` + /// implementation for `Vec`. This should not be able to + /// fail because we initialize the store with the genesis slot. + pub fn get_last(&self) -> Result { + let found = self.0.last()?.unwrap(); + let slot = deserialize(&found.1)?; + Ok(slot) + } + + /// Retrieve records count + pub fn len(&self) -> usize { + self.0.len() + } + + pub fn is_empty(&self) -> bool { + self.0.len() == 0 + } +} + +/// Overlay structure over a [`SlotStore`] instance. +pub struct SlotStoreOverlay(SledDbOverlayPtr); + +impl SlotStoreOverlay { + pub fn new(overlay: SledDbOverlayPtr) -> Result { + overlay.lock().unwrap().open_tree(SLED_SLOT_TREE)?; + Ok(Self(overlay)) + } + + /// Fetch given id from the slot store. + pub fn get(&self, id: u64) -> Result> { + match self.0.lock().unwrap().get(SLED_SLOT_TREE, &id.to_be_bytes())? { + Some(found) => Ok(found.to_vec()), + None => Err(Error::SlotNotFound(id)), + } + } +} diff --git a/src/consensus/proto/protocol_sync.rs b/src/consensus/proto/protocol_sync.rs index f301ebc0e..bcd03bfc4 100644 --- a/src/consensus/proto/protocol_sync.rs +++ b/src/consensus/proto/protocol_sync.rs @@ -21,12 +21,12 @@ use async_trait::async_trait; use log::{debug, error, info}; use smol::Executor; -use darkfi_sdk::blockchain::SlotCheckpoint; +use darkfi_sdk::blockchain::Slot; use crate::{ consensus::{ block::{BlockInfo, BlockOrder, BlockResponse}, - state::{SlotCheckpointRequest, SlotCheckpointResponse}, + state::{SlotRequest, SlotResponse}, ValidatorStatePtr, }, net::{ @@ -42,9 +42,9 @@ const BATCH: u64 = 10; pub struct ProtocolSync { channel: ChannelPtr, request_sub: MessageSubscription, - slot_checkpoin_request_sub: MessageSubscription, + slot_request_sub: MessageSubscription, block_sub: MessageSubscription, - slot_checkpoints_sub: MessageSubscription, + slots_sub: MessageSubscription, jobsman: ProtocolJobsManagerPtr, state: ValidatorStatePtr, p2p: P2pPtr, @@ -60,21 +60,21 @@ impl ProtocolSync { ) -> Result { let msg_subsystem = channel.get_message_subsystem(); msg_subsystem.add_dispatch::().await; - msg_subsystem.add_dispatch::().await; + msg_subsystem.add_dispatch::().await; msg_subsystem.add_dispatch::().await; - msg_subsystem.add_dispatch::().await; + msg_subsystem.add_dispatch::().await; let request_sub = channel.subscribe_msg::().await?; - let slot_checkpoin_request_sub = channel.subscribe_msg::().await?; + let slot_request_sub = channel.subscribe_msg::().await?; let block_sub = channel.subscribe_msg::().await?; - let slot_checkpoints_sub = channel.subscribe_msg::().await?; + let slots_sub = channel.subscribe_msg::().await?; Ok(Arc::new(Self { channel: channel.clone(), request_sub, - slot_checkpoin_request_sub, + slot_request_sub, block_sub, - slot_checkpoints_sub, + slots_sub, jobsman: ProtocolJobsManager::new("SyncProtocol", channel), state, p2p, @@ -221,17 +221,17 @@ impl ProtocolSync { } } - async fn handle_receive_slot_checkpoint_request(self: Arc) -> Result<()> { + async fn handle_receive_slot_request(self: Arc) -> Result<()> { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", + target: "consensus::protocol_sync::handle_receive_slot_request()", "START" ); loop { - let request = match self.slot_checkpoin_request_sub.receive().await { + let request = match self.slot_request_sub.receive().await { Ok(v) => v, Err(e) => { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", + target: "consensus::protocol_sync::handle_receive_slot_request()", "recv fail: {}", e ); @@ -240,40 +240,34 @@ impl ProtocolSync { }; debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", + target: "consensus::protocol_sync::handle_receive_slot_request()", "received {:?}", request ); // Extra validations can be added here let key = request.slot; - let slot_checkpoints = match self - .state - .read() - .await - .blockchain - .get_slot_checkpoints_after(key, BATCH) - { + let slots = match self.state.read().await.blockchain.get_slots_after(key, BATCH) { Ok(v) => v, Err(e) => { error!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", - "get_slot_checkpoints_after fail: {}", + target: "consensus::protocol_sync::handle_receive_slot_request()", + "get_slots_after fail: {}", e ); continue } }; debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", - "Found {} slot checkpoints", - slot_checkpoints.len() + target: "consensus::protocol_sync::handle_receive_slot_request()", + "Found {} slots", + slots.len() ); - let response = SlotCheckpointResponse { slot_checkpoints }; + let response = SlotResponse { slots }; if let Err(e) = self.channel.send(response).await { error!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint_request()", + target: "consensus::protocol_sync::handle_receive_slot_request()", "channel send fail: {}", e ) @@ -281,18 +275,18 @@ impl ProtocolSync { } } - async fn handle_receive_slot_checkpoint(self: Arc) -> Result<()> { + async fn handle_receive_slot(self: Arc) -> Result<()> { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", + target: "consensus::protocol_sync::handle_receive_slot()", "START" ); let exclude_list = vec![self.channel.address()]; loop { - let slot_checkpoint = match self.slot_checkpoints_sub.receive().await { + let slot = match self.slots_sub.receive().await { Ok(v) => v, Err(e) => { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", + target: "consensus::protocol_sync::handle_receive_slot()", "recv fail: {}", e ); @@ -303,7 +297,7 @@ impl ProtocolSync { // Check if node has finished syncing its blockchain if !self.state.read().await.synced { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", + target: "consensus::protocol_sync::handle_receive_slot()", "Node still syncing blockchain, skipping..." ); continue @@ -321,7 +315,7 @@ impl ProtocolSync { let slot = participating.unwrap(); if current >= slot { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", + target: "consensus::protocol_sync::handle_receive_slot()", "node runs in consensus mode, skipping..." ); continue @@ -330,36 +324,28 @@ impl ProtocolSync { } info!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", - "Received slot checkpoint: {}", - slot_checkpoint.slot + target: "consensus::protocol_sync::handle_receive_slot()", + "Received slot: {}", + slot.id ); debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", - "Processing received slot checkpoint" + target: "consensus::protocol_sync::handle_receive_slot()", + "Processing received slot" ); - let slot_checkpoint_copy = (*slot_checkpoint).clone(); - match self - .state - .write() - .await - .receive_finalized_slot_checkpoints(slot_checkpoint_copy.clone()) - .await - { + let slot_copy = (*slot).clone(); + match self.state.write().await.receive_finalized_slots(slot_copy.clone()).await { Ok(v) => { if v { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", - "slot checkpoint processed successfully, broadcasting..." + target: "consensus::protocol_sync::handle_receive_slot()", + "slot processed successfully, broadcasting..." ); - if let Err(e) = self - .p2p - .broadcast_with_exclude(slot_checkpoint_copy, &exclude_list) - .await + if let Err(e) = + self.p2p.broadcast_with_exclude(slot_copy, &exclude_list).await { error!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", + target: "consensus::protocol_sync::handle_receive_slot()", "p2p broadcast fail: {}", e ); @@ -368,8 +354,8 @@ impl ProtocolSync { } Err(e) => { debug!( - target: "consensus::protocol_sync::handle_receive_slot_checkpoint()", - "error processing finalized slot checkpoint: {}", + target: "consensus::protocol_sync::handle_receive_slot()", + "error processing finalized slot: {}", e ); } @@ -386,13 +372,10 @@ impl ProtocolBase for ProtocolSync { self.jobsman.clone().spawn(self.clone().handle_receive_request(), executor.clone()).await; self.jobsman .clone() - .spawn(self.clone().handle_receive_slot_checkpoint_request(), executor.clone()) + .spawn(self.clone().handle_receive_slot_request(), executor.clone()) .await; self.jobsman.clone().spawn(self.clone().handle_receive_block(), executor.clone()).await; - self.jobsman - .clone() - .spawn(self.clone().handle_receive_slot_checkpoint(), executor.clone()) - .await; + self.jobsman.clone().spawn(self.clone().handle_receive_slot(), executor.clone()).await; debug!(target: "consensus::protocol_sync::start()", "END"); Ok(()) } diff --git a/src/consensus/proto/protocol_sync_consensus.rs b/src/consensus/proto/protocol_sync_consensus.rs index ca4fb8c9f..ebfbe2244 100644 --- a/src/consensus/proto/protocol_sync_consensus.rs +++ b/src/consensus/proto/protocol_sync_consensus.rs @@ -23,10 +23,7 @@ use smol::Executor; use crate::{ consensus::{ - state::{ - ConsensusRequest, ConsensusResponse, ConsensusSlotCheckpointsRequest, - ConsensusSlotCheckpointsResponse, - }, + state::{ConsensusRequest, ConsensusResponse, ConsensusSyncRequest, ConsensusSyncResponse}, ValidatorStatePtr, }, net::{ @@ -39,7 +36,7 @@ use crate::{ pub struct ProtocolSyncConsensus { channel: ChannelPtr, request_sub: MessageSubscription, - slot_checkpoints_request_sub: MessageSubscription, + sync_request_sub: MessageSubscription, jobsman: ProtocolJobsManagerPtr, state: ValidatorStatePtr, } @@ -52,16 +49,15 @@ impl ProtocolSyncConsensus { ) -> Result { let msg_subsystem = channel.get_message_subsystem(); msg_subsystem.add_dispatch::().await; - msg_subsystem.add_dispatch::().await; + msg_subsystem.add_dispatch::().await; let request_sub = channel.subscribe_msg::().await?; - let slot_checkpoints_request_sub = - channel.subscribe_msg::().await?; + let sync_request_sub = channel.subscribe_msg::().await?; Ok(Arc::new(Self { channel: channel.clone(), request_sub, - slot_checkpoints_request_sub, + sync_request_sub, jobsman: ProtocolJobsManager::new("SyncConsensusProtocol", channel), state, })) @@ -110,7 +106,7 @@ impl ProtocolSyncConsensus { vec![] } }; - let slot_checkpoints = lock.consensus.slot_checkpoints.clone(); + let slots = lock.consensus.slots.clone(); let mut f_history = vec![]; for f in &lock.consensus.f_history { let f_str = format!("{:}", f); @@ -127,7 +123,7 @@ impl ProtocolSyncConsensus { current_slot, forks, pending_txs, - slot_checkpoints, + slots, f_history, err_history, nullifiers, @@ -142,17 +138,17 @@ impl ProtocolSyncConsensus { } } - async fn handle_receive_slot_checkpoints_request(self: Arc) -> Result<()> { + async fn handle_receive_sync_request(self: Arc) -> Result<()> { debug!( - target: "consensus::protocol_sync_consensus::handle_receive_slot_checkpoints_request()", + target: "consensus::protocol_sync_consensus::handle_receive_sync_request()", "START" ); loop { - let req = match self.slot_checkpoints_request_sub.receive().await { + let req = match self.sync_request_sub.receive().await { Ok(v) => v, Err(e) => { debug!( - target: "consensus::protocol_sync_consensus::handle_receive_slot_checkpoints_request()", + target: "consensus::protocol_sync_consensus::handle_receive_sync_request()", "recv fail: {}", e ); @@ -161,7 +157,7 @@ impl ProtocolSyncConsensus { }; debug!( - target: "consensus::protocol_sync_consensus::handle_receive_slot_checkpoints_request()", + target: "consensus::protocol_sync_consensus::handle_receive_sync_request()", "received {:?}", req ); @@ -170,11 +166,11 @@ impl ProtocolSyncConsensus { let lock = self.state.read().await; let bootstrap_slot = lock.consensus.bootstrap_slot; let proposing = lock.consensus.proposing; - let is_empty = lock.consensus.slot_checkpoints_is_empty(); - let response = ConsensusSlotCheckpointsResponse { bootstrap_slot, proposing, is_empty }; + let is_empty = lock.consensus.slots_is_empty(); + let response = ConsensusSyncResponse { bootstrap_slot, proposing, is_empty }; if let Err(e) = self.channel.send(response).await { error!( - target: "consensus::protocol_sync_consensus::handle_receive_slot_checkpoints_request()", + target: "consensus::protocol_sync_consensus::handle_receive_sync_request()", "channel send fail: {}", e ); @@ -194,7 +190,7 @@ impl ProtocolBase for ProtocolSyncConsensus { self.jobsman.clone().spawn(self.clone().handle_receive_request(), executor.clone()).await; self.jobsman .clone() - .spawn(self.clone().handle_receive_slot_checkpoints_request(), executor.clone()) + .spawn(self.clone().handle_receive_sync_request(), executor.clone()) .await; debug!( target: "consensus::protocol_sync_consensus::start()", diff --git a/src/consensus/state.rs b/src/consensus/state.rs index 21c3f9d59..1d58bee17 100644 --- a/src/consensus/state.rs +++ b/src/consensus/state.rs @@ -17,7 +17,7 @@ */ use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::MerkleTree, pasta::{group::ff::PrimeField, pallas}, }; @@ -74,8 +74,8 @@ pub struct ConsensusState { pub forks: Vec, /// Current epoch pub epoch: u64, - /// Hot/live slot checkpoints - pub slot_checkpoints: Vec, + /// Hot/live slots + pub slots: Vec, /// Last slot leaders count pub previous_leaders: u64, /// Controller output history @@ -118,7 +118,7 @@ impl ConsensusState { checked_finalization: 0, forks: vec![], epoch: 0, - slot_checkpoints: vec![], + slots: vec![], previous_leaders: 0, f_history: vec![constants::FLOAT10_ZERO.clone()], err_history: vec![constants::FLOAT10_ZERO.clone(), constants::FLOAT10_ZERO.clone()], @@ -155,26 +155,19 @@ impl ConsensusState { Ok(()) } - /// Generate current slot checkpoint - fn generate_slot_checkpoint( + /// Generate current slot + fn generate_slot( &mut self, fork_hashes: Vec, fork_previous_hashes: Vec, sigma1: pallas::Base, sigma2: pallas::Base, ) { - let slot = self.time_keeper.current_slot(); + let id = self.time_keeper.current_slot(); let previous_eta = self.get_previous_eta(); - let checkpoint = SlotCheckpoint { - slot, - previous_eta, - fork_hashes, - fork_previous_hashes, - sigma1, - sigma2, - }; - info!(target: "consensus::state", "generate_slot_checkpoint: {:?}", checkpoint); - self.slot_checkpoints.push(checkpoint); + let slot = Slot { id, previous_eta, fork_hashes, fork_previous_hashes, sigma1, sigma2 }; + info!(target: "consensus::state", "generate_slot: {:?}", slot); + self.slots.push(slot); } // Initialize node lead coins and set current epoch and eta. @@ -185,7 +178,7 @@ impl ConsensusState { Ok(()) } - /// Check if new epoch has started and generate slot checkpoint. + /// Check if new epoch has started and generate slot. /// Returns flag to signify if epoch has changed. pub async fn epoch_changed( &mut self, @@ -194,7 +187,7 @@ impl ConsensusState { sigma1: pallas::Base, sigma2: pallas::Base, ) -> Result { - self.generate_slot_checkpoint(fork_hashes, fork_previous_hashes, sigma1, sigma2); + self.generate_slot(fork_hashes, fork_previous_hashes, sigma1, sigma2); let epoch = self.time_keeper.current_epoch(); if epoch <= self.epoch { return Ok(false) @@ -558,34 +551,34 @@ impl ConsensusState { pallas::Base::from_repr(bytes).unwrap() } - /// Auxillary function to retrieve slot checkpoint of provided slot UID. - pub fn get_slot_checkpoint(&self, slot: u64) -> Result { - // Check hot/live slot checkpoints - for slot_checkpoint in self.slot_checkpoints.iter().rev() { - if slot_checkpoint.slot == slot { - return Ok(slot_checkpoint.clone()) + /// Auxillary function to retrieve slot of provided slot UID. + pub fn get_slot(&self, id: u64) -> Result { + // Check hot/live slotz + for slot in self.slots.iter().rev() { + if slot.id == id { + return Ok(slot.clone()) } } // Check if slot is finalized - if let Ok(slot_checkpoints) = self.blockchain.get_slot_checkpoints_by_slot(&[slot]) { - if !slot_checkpoints.is_empty() { - if let Some(slot_checkpoint) = &slot_checkpoints[0] { - return Ok(slot_checkpoint.clone()) + if let Ok(slots) = self.blockchain.get_slots_by_id(&[id]) { + if !slots.is_empty() { + if let Some(known_slot) = &slots[0] { + return Ok(known_slot.clone()) } } } - Err(Error::SlotCheckpointNotFound(slot)) + Err(Error::SlotNotFound(id)) } - /// Auxillary function to check if node has seen current or previous slot checkpoints. + /// Auxillary function to check if node has seen current or previous slots. /// This check ensures that either the slots exist in memory or node has seen the finalization of these slots. - pub fn slot_checkpoints_is_empty(&self) -> bool { + pub fn slots_is_empty(&self) -> bool { let current_slot = self.time_keeper.current_slot(); - if self.get_slot_checkpoint(current_slot).is_ok() { + if self.get_slot(current_slot).is_ok() { return false } let previous_slot = current_slot - 1; - self.get_slot_checkpoint(previous_slot).is_err() + self.get_slot(previous_slot).is_err() } /// Auxillary function to update all fork state checkpoints to nodes coins current canonical states. @@ -623,7 +616,7 @@ impl ConsensusState { self.participating = None; self.proposing = false; self.forks = vec![]; - self.slot_checkpoints = vec![]; + self.slots = vec![]; self.previous_leaders = 0; self.f_history = vec![constants::FLOAT10_ZERO.clone()]; self.err_history = vec![constants::FLOAT10_ZERO.clone(), constants::FLOAT10_ZERO.clone()]; @@ -652,8 +645,8 @@ pub struct ConsensusResponse { pub forks: Vec, /// Pending transactions pub pending_txs: Vec, - /// Hot/live slot checkpoints - pub slot_checkpoints: Vec, + /// Hot/live slots + pub slots: Vec, // TODO: When Float10 supports encoding/decoding this should be // replaced by directly using Vec /// Controller output history @@ -672,60 +665,60 @@ impl net::Message for ConsensusResponse { /// Auxiliary structure used for consensus syncing. #[derive(Debug, SerialEncodable, SerialDecodable)] -pub struct ConsensusSlotCheckpointsRequest {} +pub struct ConsensusSyncRequest {} -impl net::Message for ConsensusSlotCheckpointsRequest { +impl net::Message for ConsensusSyncRequest { fn name() -> &'static str { - "consensusslotcheckpointsrequest" + "consensussyncrequest" } } /// Auxiliary structure used for consensus syncing. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)] -pub struct ConsensusSlotCheckpointsResponse { +pub struct ConsensusSyncResponse { /// Node known bootstrap slot pub bootstrap_slot: u64, /// Node is able to propose proposals pub proposing: bool, - /// Node has hot/live slot checkpoints + /// Node has hot/live slots pub is_empty: bool, } -impl net::Message for ConsensusSlotCheckpointsResponse { +impl net::Message for ConsensusSyncResponse { fn name() -> &'static str { - "consensusslotcheckpointsresponse" + "consensussyncresponse" } } -impl net::Message for SlotCheckpoint { +impl net::Message for Slot { fn name() -> &'static str { - "slotcheckpoint" + "slot" } } -/// Auxiliary structure used for slot checkpoints syncing +/// Auxiliary structure used for slots syncing #[derive(Debug, Clone, SerialEncodable, SerialDecodable)] -pub struct SlotCheckpointRequest { +pub struct SlotRequest { /// Slot UID pub slot: u64, } -impl net::Message for SlotCheckpointRequest { +impl net::Message for SlotRequest { fn name() -> &'static str { - "slotcheckpointrequest" + "slotrequest" } } -/// Auxiliary structure used for slot checkpoints syncing +/// Auxiliary structure used for slots syncing #[derive(Debug, Clone, SerialEncodable, SerialDecodable)] -pub struct SlotCheckpointResponse { +pub struct SlotResponse { /// Response blocks. - pub slot_checkpoints: Vec, + pub slots: Vec, } -impl net::Message for SlotCheckpointResponse { +impl net::Message for SlotResponse { fn name() -> &'static str { - "slotcheckpointresponse" + "slotresponse" } } diff --git a/src/consensus/task/block_sync.rs b/src/consensus/task/block_sync.rs index a51bcf801..e559b4d02 100644 --- a/src/consensus/task/block_sync.rs +++ b/src/consensus/task/block_sync.rs @@ -19,7 +19,7 @@ use crate::{ consensus::{ block::{BlockOrder, BlockResponse}, - state::{SlotCheckpointRequest, SlotCheckpointResponse}, + state::{SlotRequest, SlotResponse}, ValidatorStatePtr, }, net, Result, @@ -34,40 +34,39 @@ pub async fn block_sync_task(p2p: net::P2pPtr, state: ValidatorStatePtr) -> Resu Some(channel) => { let msg_subsystem = channel.get_message_subsystem(); - // Communication setup for slot checkpoints - msg_subsystem.add_dispatch::().await; - let slot_checkpoint_response_sub = - channel.subscribe_msg::().await?; + // Communication setup for slots + msg_subsystem.add_dispatch::().await; + let slot_response_sub = channel.subscribe_msg::().await?; // Communication setup for blocks msg_subsystem.add_dispatch::().await; let block_response_sub = channel.subscribe_msg::().await?; - // Node loops until both slot checkpoints and blocks have been synced - let mut slot_checkpoints_synced = false; + // Node loops until both slots and blocks have been synced + let mut slots_synced = false; let mut blocks_synced = false; loop { - // Node sends the last known slot checkpoint of the canonical blockchain + // Node sends the last known slot of the canonical blockchain // and loops until the response is the same slot (used to utilize batch requests). - let mut last = state.read().await.blockchain.last_slot_checkpoint()?; - info!(target: "consensus::block_sync", "Last known slot checkpoint: {:?}", last.slot); + let mut last = state.read().await.blockchain.last_slot()?; + info!(target: "consensus::block_sync", "Last known slot: {:?}", last.id); loop { - // Node creates a `SlotCheckpointRequest` and sends it - let request = SlotCheckpointRequest { slot: last.slot }; + // Node creates a `SlotRequest` and sends it + let request = SlotRequest { slot: last.id }; channel.send(request).await?; // Node stores response data. - let resp = slot_checkpoint_response_sub.receive().await?; + let resp = slot_response_sub.receive().await?; - // Verify and store retrieved checkpoints - debug!(target: "consensus::block_sync", "block_sync_task(): Processing received slot checkpoints"); - state.write().await.receive_slot_checkpoints(&resp.slot_checkpoints).await?; + // Verify and store retrieveds + debug!(target: "consensus::block_sync", "block_sync_task(): Processing received slots"); + state.write().await.receive_slots(&resp.slots).await?; - let last_received = state.read().await.blockchain.last_slot_checkpoint()?; - info!(target: "consensus::block_sync", "Last received slot checkpoint: {:?}", last_received.slot); + let last_received = state.read().await.blockchain.last_slot()?; + info!(target: "consensus::block_sync", "Last received slot: {:?}", last_received.id); - if last.slot == last_received.slot { + if last.id == last_received.id { break } @@ -75,9 +74,9 @@ pub async fn block_sync_task(p2p: net::P2pPtr, state: ValidatorStatePtr) -> Resu last = last_received; } - // We force a recheck of slot checkpoints after blocks have been synced + // We force a recheck of slots after blocks have been synced if blocks_synced { - slot_checkpoints_synced = true; + slots_synced = true; } // Node sends the last known block hash of the canonical blockchain @@ -106,11 +105,11 @@ pub async fn block_sync_task(p2p: net::P2pPtr, state: ValidatorStatePtr) -> Resu break } - slot_checkpoints_synced = false; + slots_synced = false; last = last_received; } - if slot_checkpoints_synced && blocks_synced { + if slots_synced && blocks_synced { break } } diff --git a/src/consensus/task/consensus_sync.rs b/src/consensus/task/consensus_sync.rs index 11d9e6fc7..2984f0743 100644 --- a/src/consensus/task/consensus_sync.rs +++ b/src/consensus/task/consensus_sync.rs @@ -20,10 +20,7 @@ use log::{info, warn}; use crate::{ consensus::{ - state::{ - ConsensusRequest, ConsensusResponse, ConsensusSlotCheckpointsRequest, - ConsensusSlotCheckpointsResponse, - }, + state::{ConsensusRequest, ConsensusResponse, ConsensusSyncRequest, ConsensusSyncResponse}, Float10, ValidatorStatePtr, }, net::P2pPtr, @@ -51,15 +48,15 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul return Ok(true) } - // Node iterates the channel peers to check if at least on peer has seen slot checkpoints + // Node iterates the channel peers to check if at least on peer has seen slots let mut peer = None; for channel in values { // Communication setup let msg_subsystem = channel.get_message_subsystem(); - msg_subsystem.add_dispatch::().await; - let response_sub = channel.subscribe_msg::().await?; - // Node creates a `ConsensusSlotCheckpointsRequest` and sends it - let request = ConsensusSlotCheckpointsRequest {}; + msg_subsystem.add_dispatch::().await; + let response_sub = channel.subscribe_msg::().await?; + // Node creates a `ConsensusSyncRequest` and sends it + let request = ConsensusSyncRequest {}; channel.send(request).await?; // Node checks response let response = response_sub.receive().await?; @@ -72,7 +69,7 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul continue } if response.is_empty { - warn!(target: "consensus::consensus_sync", "Node has not seen any slot checkpoints, retrying..."); + warn!(target: "consensus::consensus_sync", "Node has not seen any slots, retrying..."); continue } // Keep peer to ask for consensus state @@ -83,10 +80,10 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul // Release channels lock drop(channels_map); - // If no peer knows about any slot checkpoints, that means that the network was bootstrapped or restarted + // If no peer knows about any slots, that means that the network was bootstrapped or restarted // and no node has started consensus. if peer.is_none() { - warn!(target: "consensus::consensus_sync", "No node that has seen any slot checkpoints was found, or network was just boostrapped."); + warn!(target: "consensus::consensus_sync", "No node that has seen any slots was found, or network was just boostrapped."); let mut lock = state.write().await; lock.consensus.bootstrap_slot = current_slot; lock.consensus.init_coins().await?; @@ -129,7 +126,7 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul // Verify that the node has received all finalized blocks loop { - if !state.read().await.blockchain.has_slot(response.current_slot)? { + if !state.read().await.blockchain.has_slot_order(response.current_slot)? { warn!(target: "consensus::consensus_sync", "Node has not finished finalization, retrying..."); sleep(1).await; continue @@ -146,7 +143,7 @@ pub async fn consensus_sync_task(p2p: P2pPtr, state: ValidatorStatePtr) -> Resul lock.consensus.bootstrap_slot = response.bootstrap_slot; lock.consensus.forks = forks; lock.append_pending_txs(&response.pending_txs).await; - lock.consensus.slot_checkpoints = response.slot_checkpoints.clone(); + lock.consensus.slots = response.slots.clone(); lock.consensus.previous_leaders = 1; let mut f_history = vec![]; for f in &response.f_history { diff --git a/src/consensus/task/proposal.rs b/src/consensus/task/proposal.rs index ff98f86fe..76ddecf00 100644 --- a/src/consensus/task/proposal.rs +++ b/src/consensus/task/proposal.rs @@ -174,7 +174,7 @@ async fn consensus_loop( /// async function to wait and execute consensus protocol propose period. /// Propose period consists of 2 parts: -/// - Generate slot sigmas and checkpoint +/// - Generate current slot /// - Check if slot leader to generate and broadcast proposal /// Returns flag in case node needs to resync. async fn propose_period(consensus_p2p: P2pPtr, state: ValidatorStatePtr) -> bool { @@ -191,7 +191,7 @@ async fn propose_period(consensus_p2p: P2pPtr, state: ValidatorStatePtr) -> bool // Retrieve slot sigmas let (sigma1, sigma2) = state.write().await.consensus.sigmas(); - // Node checks if epoch has changed and generate slot checkpoint + // Node checks if epoch has changed and generate slot let epoch_changed = state .write() .await @@ -245,7 +245,6 @@ async fn propose_period(consensus_p2p: P2pPtr, state: ValidatorStatePtr) -> bool } // Node stores the proposal and broadcast to rest nodes - info!(target: "consensus::proposal", "consensus: Node is the slot leader: Proposed block: {}", proposal); debug!(target: "consensus::proposal", "consensus: Full proposal: {:?}", proposal); match state @@ -304,9 +303,9 @@ async fn finalization_period( // Check if any forks can be finalized match state.write().await.chain_finalization().await { - Ok((to_broadcast_block, to_broadcast_slot_checkpoints)) => { + Ok((to_broadcast_block, to_broadcast_slots)) => { // Broadcasting in background - if !to_broadcast_block.is_empty() || !to_broadcast_slot_checkpoints.is_empty() { + if !to_broadcast_block.is_empty() || !to_broadcast_slots.is_empty() { ex.spawn(async move { // Broadcast finalized blocks info, if any: info!(target: "consensus::proposal", "consensus: Broadcasting finalized blocks"); @@ -317,20 +316,20 @@ async fn finalization_period( } } - // Broadcast finalized slot checkpoints, if any: - info!(target: "consensus::proposal", "consensus: Broadcasting finalized slot checkpoints"); - for slot_checkpoint in to_broadcast_slot_checkpoints { - match sync_p2p.broadcast(slot_checkpoint).await { - Ok(()) => info!(target: "consensus::proposal", "consensus: Broadcasted slot_checkpoint"), + // Broadcast finalized slots, if any: + info!(target: "consensus::proposal", "consensus: Broadcasting finalized slots"); + for slot in to_broadcast_slots { + match sync_p2p.broadcast(slot).await { + Ok(()) => info!(target: "consensus::proposal", "consensus: Broadcasted slot"), Err(e) => { - error!(target: "consensus::proposal", "consensus: Failed broadcasting slot_checkpoint: {}", e) + error!(target: "consensus::proposal", "consensus: Failed broadcasting slot: {}", e) } } } }) .detach(); } else { - info!(target: "consensus::proposal", "consensus: No finalized blocks or slot checkpoints to broadcast"); + info!(target: "consensus::proposal", "consensus: No finalized blocks or slots to broadcast"); } } Err(e) => { diff --git a/src/consensus/validator.rs b/src/consensus/validator.rs index 4dfe5dbdb..81c6aedc5 100644 --- a/src/consensus/validator.rs +++ b/src/consensus/validator.rs @@ -20,7 +20,7 @@ use std::{collections::HashMap, io::Cursor}; use async_std::sync::{Arc, RwLock}; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::{ contract_id::{CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID}, schnorr::{SchnorrPublic, SchnorrSecret}, @@ -573,7 +573,7 @@ impl ValidatorState { }; info!(target: "consensus::validator", "receive_proposal(): Leader proof verified successfully!"); - // Validate proposal public value against coin creation slot checkpoint + // Validate proposal public value against coin creation slot let (mu_y, mu_rho) = LeadCoin::election_seeds_u64( self.consensus.get_previous_eta(), self.consensus.time_keeper.current_slot(), @@ -602,24 +602,24 @@ impl ValidatorState { return Err(Error::ProposalPublicValuesMismatched) } - // Validate proposal coin sigmas against current slot checkpoint - let checkpoint = self.consensus.get_slot_checkpoint(current)?; + // Validate proposal coin sigmas against current slot + let slot = self.consensus.get_slot(current)?; // sigma1 let prop_sigma1 = lf.public_inputs[constants::PI_SIGMA1_INDEX]; - if checkpoint.sigma1 != prop_sigma1 { + if slot.sigma1 != prop_sigma1 { error!( target: "consensus::validator", "receive_proposal(): Failed to verify public value sigma1: {:?}, to proposed: {:?}", - checkpoint.sigma1, prop_sigma1 + slot.sigma1, prop_sigma1 ); } // sigma2 let prop_sigma2 = lf.public_inputs[constants::PI_SIGMA2_INDEX]; - if checkpoint.sigma2 != prop_sigma2 { + if slot.sigma2 != prop_sigma2 { error!( target: "consensus::validator", "receive_proposal(): Failed to verify public value sigma2: {:?}, to proposed: {:?}", - checkpoint.sigma2, prop_sigma2 + slot.sigma2, prop_sigma2 ); } } @@ -719,8 +719,8 @@ impl ValidatorState { /// - If the node has observed the creation of a fork chain and no other forks exists at same or greater height, /// it finalizes (appends to canonical blockchain) all proposals in that fork chain. /// When fork chain proposals are finalized, the rest of fork chains are removed and all - /// slot checkpoints are apppended to canonical state. - pub async fn chain_finalization(&mut self) -> Result<(Vec, Vec)> { + /// slots are apppended to canonical state. + pub async fn chain_finalization(&mut self) -> Result<(Vec, Vec)> { let slot = self.consensus.time_keeper.current_slot(); info!(target: "consensus::validator", "chain_finalization(): Started finalization check for slot: {}", slot); // Set last slot finalization check occured to current slot @@ -827,37 +827,36 @@ impl ValidatorState { self.consensus.coins_tree = last_state_checkpoint.coins_tree; self.consensus.nullifiers = last_state_checkpoint.nullifiers; - // Adding finalized slot checkpoints to canonical - let finalized_slot_checkpoints: Vec = - self.consensus.slot_checkpoints.clone(); + // Adding finalized slots to canonical + let finalized_slots: Vec = self.consensus.slots.clone(); debug!( target: "consensus::validator", - "consensus: Adding {} finalized slot checkpoints to canonical chain.", - finalized_slot_checkpoints.len() + "consensus: Adding {} finalized slots to canonical chain.", + finalized_slots.len() ); - match self.blockchain.add_slot_checkpoints(&finalized_slot_checkpoints) { + match self.blockchain.add_slots(&finalized_slots) { Ok(v) => v, Err(e) => { error!( target: "consensus::validator", - "consensus: Failed appending finalized slot checkpoints to canonical chain: {}", + "consensus: Failed appending finalized slots to canonical chain: {}", e ); return Err(e) } }; - // Resetting forks and slot checkpoints + // Resetting forks and slots self.consensus.forks = vec![]; - self.consensus.slot_checkpoints = vec![]; + self.consensus.slots = vec![]; // Purge pending erroneous txs since canonical state has been changed if let Err(e) = self.purge_pending_txs().await { error!(target: "consensus::validator", "consensus: Purging pending transactions failed: {}", e); } - Ok((finalized, finalized_slot_checkpoints)) + Ok((finalized, finalized_slots)) } // ========================== @@ -1178,47 +1177,41 @@ impl ValidatorState { Ok(erroneous_txs) } - /// Append to canonical state received finalized slot checkpoints from block sync task. - pub async fn receive_slot_checkpoints( - &mut self, - slot_checkpoints: &[SlotCheckpoint], - ) -> Result<()> { - info!(target: "consensus::validator", "receive_slot_checkpoints(): Appending slot checkpoints to ledger"); + /// Append to canonical state received finalized slots from block sync task. + pub async fn receive_slots(&mut self, slots: &[Slot]) -> Result<()> { + info!(target: "consensus::validator", "receive_slots(): Appending slots to ledger"); let mut filtered = vec![]; - for slot_checkpoint in slot_checkpoints { - if slot_checkpoint.slot > self.consensus.time_keeper.current_slot() { - warn!(target: "consensus::validator", "receive_slot_checkpoints(): Ignoring future slot checkpoint: {}", slot_checkpoint.slot); + for slot in slots { + if slot.id > self.consensus.time_keeper.current_slot() { + warn!(target: "consensus::validator", "receive_slots(): Ignoring future slot: {}", slot.id); continue } - filtered.push(slot_checkpoint.clone()); + filtered.push(slot.clone()); } - self.blockchain.add_slot_checkpoints(&filtered[..])?; + self.blockchain.add_slots(&filtered[..])?; Ok(()) } - /// Validate and append to canonical state received finalized slot checkpoint. - /// Returns boolean flag indicating already existing slot checkpoint. - pub async fn receive_finalized_slot_checkpoints( - &mut self, - slot_checkpoint: SlotCheckpoint, - ) -> Result { - match self.blockchain.has_slot_checkpoint(&slot_checkpoint) { + /// Validate and append to canonical state received finalized slot. + /// Returns boolean flag indicating already existing slot. + pub async fn receive_finalized_slots(&mut self, slot: Slot) -> Result { + match self.blockchain.has_slot(&slot) { Ok(v) => { if v { info!( target: "consensus::validator", - "receive_finalized_slot_checkpoints(): Existing slot checkpoint received" + "receive_finalized_slots(): Existing slot received" ); return Ok(false) } } Err(e) => { - error!(target: "consensus::validator", "receive_finalized_slot_checkpoints(): failed checking for has_slot_checkpoint(): {}", e); + error!(target: "consensus::validator", "receive_finalized_slots(): failed checking for has_slot(): {}", e); return Ok(false) } }; - self.receive_slot_checkpoints(&[slot_checkpoint]).await?; + self.receive_slots(&[slot]).await?; Ok(true) } } diff --git a/src/contract/consensus/src/client/proposal_v1.rs b/src/contract/consensus/src/client/proposal_v1.rs index 605796123..3333580cb 100644 --- a/src/contract/consensus/src/client/proposal_v1.rs +++ b/src/contract/consensus/src/client/proposal_v1.rs @@ -28,7 +28,7 @@ use darkfi_money_contract::{ model::{Coin, ConsensusInput, ConsensusOutput}, }; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, bridgetree::Hashable, crypto::{ ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, @@ -112,8 +112,8 @@ impl ConsensusProposalRevealed { pub struct ConsensusProposalCallBuilder { /// `ConsensusOwnCoin` we're given to use in this builder pub owncoin: ConsensusOwnCoin, - /// Rewarded slot checkpoint - pub slot_checkpoint: SlotCheckpoint, + /// Rewarded slot + pub slot: Slot, /// Extending fork last proposal/block hash pub fork_hash: blake3::Hash, /// Extending fork second to last proposal/block hash @@ -164,9 +164,9 @@ impl ConsensusProposalCallBuilder { info!("Building Consensus::ProposalV1 VRF proof"); let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32); - vrf_input.extend_from_slice(&self.slot_checkpoint.previous_eta.to_repr()); + vrf_input.extend_from_slice(&self.slot.previous_eta.to_repr()); vrf_input.extend_from_slice(self.fork_previous_hash.as_bytes()); - vrf_input.extend_from_slice(&pallas::Base::from(self.slot_checkpoint.slot).to_repr()); + vrf_input.extend_from_slice(&pallas::Base::from(self.slot.id).to_repr()); let vrf_proof = VrfProof::prove(input.secret, &vrf_input, &mut OsRng); info!("Building Consensus::ProposalV1 ZK proof"); @@ -175,7 +175,7 @@ impl ConsensusProposalCallBuilder { &self.proposal_pk, &input, &output, - &self.slot_checkpoint, + &self.slot, &vrf_proof, )?; @@ -234,7 +234,7 @@ fn create_proposal_proof( pk: &ProvingKey, input: &ConsensusBurnInputInfo, output: &ConsensusMintOutputInfo, - checkpoint: &SlotCheckpoint, + slot: &Slot, vrf_proof: &VrfProof, ) -> Result<(Proof, ConsensusProposalRevealed)> { // TODO: fork_hash to be used as part of rank constrain in the proof @@ -245,9 +245,9 @@ fn create_proposal_proof( eta[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes()); let eta = pallas::Base::from_uniform_bytes(&eta); - let mu_y = poseidon_hash([MU_Y_PREFIX, eta, pallas::Base::from(checkpoint.slot)]); + let mu_y = poseidon_hash([MU_Y_PREFIX, eta, pallas::Base::from(slot.id)]); let y = poseidon_hash([seed, mu_y]); - let mu_rho = poseidon_hash([MU_RHO_PREFIX, eta, pallas::Base::from(checkpoint.slot)]); + let mu_rho = poseidon_hash([MU_RHO_PREFIX, eta, pallas::Base::from(slot.id)]); let rho = poseidon_hash([seed, mu_rho]); // Derive the input's nullifier @@ -307,8 +307,8 @@ fn create_proposal_proof( y, mu_rho, rho, - sigma1: checkpoint.sigma1, - sigma2: checkpoint.sigma2, + sigma1: slot.sigma1, + sigma2: slot.sigma2, headstart: HEADSTART, }; diff --git a/src/contract/consensus/src/entrypoint/proposal_v1.rs b/src/contract/consensus/src/entrypoint/proposal_v1.rs index 37e7a0024..47cbc06a5 100644 --- a/src/contract/consensus/src/entrypoint/proposal_v1.rs +++ b/src/contract/consensus/src/entrypoint/proposal_v1.rs @@ -23,13 +23,13 @@ use darkfi_money_contract::{ CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1, }; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::{pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode}, db::{db_contains_key, db_lookup, db_set}, error::{ContractError, ContractResult}, merkle_add, msg, pasta::{group::ff::FromUniformBytes, pallas}, - util::{get_slot_checkpoint, get_verifying_slot, get_verifying_slot_epoch}, + util::{get_slot, get_verifying_slot, get_verifying_slot_epoch}, ContractCall, }; use darkfi_serial::{deserialize, serialize, Encodable, WriteExt}; @@ -68,17 +68,17 @@ pub(crate) fn consensus_proposal_get_metadata_v1( // Grab the pedersen commitment for the minted value let output_value_coords = ¶ms.output.value_commit.to_affine().coordinates().unwrap(); - // Grab the slot checkpoint to validate consensus params against + // Grab the slot to validate consensus params against let v_slot = get_verifying_slot(); - let Some(slot_checkpoint) = get_slot_checkpoint(v_slot)? else { - msg!("[ConsensusProposalV1] Error: Missing slot checkpoint {} from db", v_slot); - return Err(ConsensusError::ProposalMissingSlotCheckpoint.into()) + let Some(slot) = get_slot(v_slot)? else { + msg!("[ConsensusProposalV1] Error: Missing slot {} from db", v_slot); + return Err(ConsensusError::ProposalMissingSlot.into()) }; - let slot_checkpoint: SlotCheckpoint = deserialize(&slot_checkpoint)?; - let slot_fp = pallas::Base::from(slot_checkpoint.slot); + let slot: Slot = deserialize(&slot)?; + let slot_fp = pallas::Base::from(slot.id); // Verify proposal extends a known fork - if !slot_checkpoint.fork_hashes.contains(¶ms.fork_hash) { + if !slot.fork_hashes.contains(¶ms.fork_hash) { msg!("[ConsensusProposalV1] Error: Proposal extends unknown fork {}", params.fork_hash); return Err(ConsensusError::ProposalExtendsUnknownFork.into()) } @@ -86,7 +86,7 @@ pub(crate) fn consensus_proposal_get_metadata_v1( // TODO: Add fork rank check using params.fork_hash // Verify sequence is correct - if !slot_checkpoint.fork_previous_hashes.contains(¶ms.fork_previous_hash) { + if !slot.fork_previous_hashes.contains(¶ms.fork_previous_hash) { let fork_prev = ¶ms.fork_previous_hash; msg!("[ConsensusProposalV1] Error: Proposal extends unknown fork {}", fork_prev); return Err(ConsensusError::ProposalExtendsUnknownFork.into()) @@ -94,7 +94,7 @@ pub(crate) fn consensus_proposal_get_metadata_v1( // Construct VRF input let mut vrf_input = Vec::with_capacity(32 + blake3::OUT_LEN + 32); - vrf_input.extend_from_slice(&slot_checkpoint.previous_eta.to_repr()); + vrf_input.extend_from_slice(&slot.previous_eta.to_repr()); vrf_input.extend_from_slice(params.fork_previous_hash.as_bytes()); vrf_input.extend_from_slice(&slot_fp.to_repr()); @@ -113,8 +113,8 @@ pub(crate) fn consensus_proposal_get_metadata_v1( let mu_y = poseidon_hash([MU_Y_PREFIX, eta, slot_fp]); let mu_rho = poseidon_hash([MU_RHO_PREFIX, eta, slot_fp]); - // Grab sigmas from slot checkpoint - let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2); + // Grab sigmas from slot + let (sigma1, sigma2) = (slot.sigma1, slot.sigma2); zk_public_inputs.push(( CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1.to_string(), diff --git a/src/contract/consensus/src/error.rs b/src/contract/consensus/src/error.rs index f2e96e8d4..380e6505e 100644 --- a/src/contract/consensus/src/error.rs +++ b/src/contract/consensus/src/error.rs @@ -20,8 +20,8 @@ use darkfi_sdk::error::ContractError; #[derive(Debug, Clone, thiserror::Error)] pub enum ConsensusError { - #[error("Missing slot checkpoint from db")] - ProposalMissingSlotCheckpoint, + #[error("Missing slot from db")] + ProposalMissingSlot, #[error("Proposal extends unknown fork")] ProposalExtendsUnknownFork, @@ -39,7 +39,7 @@ pub enum ConsensusError { impl From for ContractError { fn from(e: ConsensusError) -> Self { match e { - ConsensusError::ProposalMissingSlotCheckpoint => Self::Custom(1), + ConsensusError::ProposalMissingSlot => Self::Custom(1), ConsensusError::ProposalExtendsUnknownFork => Self::Custom(2), ConsensusError::ProposalErroneousVrfProof => Self::Custom(3), ConsensusError::CoinStillInGracePeriod => Self::Custom(4), diff --git a/src/contract/consensus/tests/genesis_stake_unstake.rs b/src/contract/consensus/tests/genesis_stake_unstake.rs index d49a6a32e..be9952cdf 100644 --- a/src/contract/consensus/tests/genesis_stake_unstake.rs +++ b/src/contract/consensus/tests/genesis_stake_unstake.rs @@ -115,7 +115,7 @@ async fn consensus_contract_genesis_stake_unstake() -> Result<()> { // We simulate the proposal of genesis slot // We progress 1 slot and simulate its proposal current_slot += 1; - let slot_checkpoint = th.generate_slot_checkpoint(current_slot).await?; + let slot = th.generate_slot(current_slot).await?; // With alice's current coin value she can become the slot proposer, // so she creates a proposal transaction to burn her staked coin, @@ -124,7 +124,7 @@ async fn consensus_contract_genesis_stake_unstake() -> Result<()> { info!(target: "consensus", "[Alice] Building proposal tx"); info!(target: "consensus", "[Alice] ===================="); let (proposal_tx, proposal_params, _proposal_signing_secret_key, proposal_output_secret_key) = - th.proposal(Holder::Alice, slot_checkpoint, alice_staked_oc.clone()).await?; + th.proposal(Holder::Alice, slot, alice_staked_oc.clone()).await?; info!(target: "consensus", "[Faucet] ==========================="); info!(target: "consensus", "[Faucet] Executing Alice proposal tx"); @@ -150,7 +150,7 @@ async fn consensus_contract_genesis_stake_unstake() -> Result<()> { // We progress after grace period current_slot += calculate_grace_period() * EPOCH_LENGTH; - th.generate_slot_checkpoint(current_slot).await?; + th.generate_slot(current_slot).await?; // Alice can request for her owncoin to get unstaked info!(target: "consensus", "[Alice] ==========================="); diff --git a/src/contract/consensus/tests/stake_unstake.rs b/src/contract/consensus/tests/stake_unstake.rs index 6ee51c216..f71f97355 100644 --- a/src/contract/consensus/tests/stake_unstake.rs +++ b/src/contract/consensus/tests/stake_unstake.rs @@ -101,19 +101,18 @@ async fn consensus_contract_stake_unstake() -> Result<()> { // We progress one slot current_slot += 1; - let slot_checkpoint = th.generate_slot_checkpoint(current_slot).await?; + let slot = th.generate_slot(current_slot).await?; // Since alice didn't wait for the grace period to pass, her proposal should fail info!(target: "consensus", "[Malicious] ====================================="); info!(target: "consensus", "[Malicious] Checking proposal before grace period"); info!(target: "consensus", "[Malicious] ====================================="); - let (proposal_tx, _, _, _) = - th.proposal(Holder::Alice, slot_checkpoint, alice_staked_oc.clone()).await?; + let (proposal_tx, _, _, _) = th.proposal(Holder::Alice, slot, alice_staked_oc.clone()).await?; th.execute_erroneous_proposal_txs(Holder::Alice, &vec![proposal_tx], current_slot, 1).await?; // We progress after grace period current_slot += (calculate_grace_period() * EPOCH_LENGTH) + EPOCH_LENGTH; - let slot_checkpoint = th.generate_slot_checkpoint(current_slot).await?; + let slot = th.generate_slot(current_slot).await?; // With alice's current coin value she can become the slot proposer, // so she creates a proposal transaction to burn her staked coin, @@ -126,7 +125,7 @@ async fn consensus_contract_stake_unstake() -> Result<()> { proposal_params, _proposal_signing_secret_key, proposal_decryption_secret_key, - ) = th.proposal(Holder::Alice, slot_checkpoint, alice_staked_oc.clone()).await?; + ) = th.proposal(Holder::Alice, slot, alice_staked_oc.clone()).await?; info!(target: "consensus", "[Faucet] ==========================="); info!(target: "consensus", "[Faucet] Executing Alice proposal tx"); @@ -152,7 +151,7 @@ async fn consensus_contract_stake_unstake() -> Result<()> { // We progress one slot current_slot += 1; - th.generate_slot_checkpoint(current_slot).await?; + th.generate_slot(current_slot).await?; // Alice can request for her owncoin to get unstaked info!(target: "consensus", "[Alice] ==========================="); @@ -201,13 +200,13 @@ async fn consensus_contract_stake_unstake() -> Result<()> { // Now we will test if we can reuse token in proposal or unstake it again current_slot += 1; - let slot_checkpoint = th.generate_slot_checkpoint(current_slot).await?; + let slot = th.generate_slot(current_slot).await?; info!(target: "consensus", "[Malicious] ========================================"); info!(target: "consensus", "[Malicious] Checking using unstaked coin in proposal"); info!(target: "consensus", "[Malicious] ========================================"); let (proposal_tx, _, _, _) = - th.proposal(Holder::Alice, slot_checkpoint, alice_unstake_request_oc.clone()).await?; + th.proposal(Holder::Alice, slot, alice_unstake_request_oc.clone()).await?; th.execute_erroneous_proposal_txs(Holder::Alice, &vec![proposal_tx], current_slot, 1).await?; info!(target: "consensus", "[Malicious] ============================="); diff --git a/src/contract/test-harness/src/consensus_proposal.rs b/src/contract/test-harness/src/consensus_proposal.rs index e738c22f9..55c40628d 100644 --- a/src/contract/test-harness/src/consensus_proposal.rs +++ b/src/contract/test-harness/src/consensus_proposal.rs @@ -25,7 +25,7 @@ use darkfi_consensus_contract::{ }; use darkfi_money_contract::{client::ConsensusOwnCoin, CONSENSUS_CONTRACT_ZKAS_PROPOSAL_NS_V1}; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::{MerkleNode, SecretKey, CONSENSUS_CONTRACT_ID}, ContractCall, }; @@ -38,7 +38,7 @@ impl TestHarness { pub async fn proposal( &mut self, holder: Holder, - slot_checkpoint: SlotCheckpoint, + slot: Slot, staked_oc: ConsensusOwnCoin, ) -> Result<(Transaction, ConsensusProposalParamsV1, SecretKey, SecretKey)> { let wallet = self.holders.get(&holder).unwrap(); @@ -54,7 +54,7 @@ impl TestHarness { // Building Consensus::Propose params let proposal_call_debris = ConsensusProposalCallBuilder { owncoin: staked_oc, - slot_checkpoint, + slot, fork_hash, fork_previous_hash: fork_hash, merkle_tree: wallet.consensus_staked_merkle_tree.clone(), diff --git a/src/contract/test-harness/src/lib.rs b/src/contract/test-harness/src/lib.rs index 3dd0e2263..74103a8b6 100644 --- a/src/contract/test-harness/src/lib.rs +++ b/src/contract/test-harness/src/lib.rs @@ -42,7 +42,7 @@ use darkfi_money_contract::{ MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, }; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::{ poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey, CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID, @@ -413,26 +413,24 @@ impl TestHarness { Ok(oc) } - pub async fn get_slot_checkpoint_by_slot(&self, slot: u64) -> Result { + pub async fn get_slot_by_slot(&self, slot: u64) -> Result { let faucet = self.holders.get(&Holder::Faucet).unwrap(); - let slot_checkpoint = - faucet.validator.read().await.blockchain.get_slot_checkpoints_by_slot(&[slot])?[0] - .clone() - .unwrap(); + let slot = + faucet.validator.read().await.blockchain.get_slots_by_id(&[slot])?[0].clone().unwrap(); - Ok(slot_checkpoint) + Ok(slot) } - pub async fn generate_slot_checkpoint(&self, slot: u64) -> Result { - // We grab the genesis slot to generate slot checkpoint + pub async fn generate_slot(&self, id: u64) -> Result { + // We grab the genesis slot to generate slot // using same consensus parameters let faucet = self.holders.get(&Holder::Faucet).unwrap(); let genesis_block = faucet.validator.read().await.consensus.genesis_block; let fork_hashes = vec![genesis_block]; let fork_previous_hashes = vec![genesis_block]; - let genesis_slot = self.get_slot_checkpoint_by_slot(0).await?; - let slot_checkpoint = SlotCheckpoint { - slot, + let genesis_slot = self.get_slot_by_slot(0).await?; + let slot = Slot { + id, previous_eta: genesis_slot.previous_eta, fork_hashes, fork_previous_hashes, @@ -440,17 +438,12 @@ impl TestHarness { sigma2: genesis_slot.sigma2, }; - // Store generated slot checkpoint + // Store generated slot for wallet in self.holders.values() { - wallet - .validator - .write() - .await - .receive_slot_checkpoints(&[slot_checkpoint.clone()]) - .await?; + wallet.validator.write().await.receive_slots(&[slot.clone()]).await?; } - Ok(slot_checkpoint) + Ok(slot) } pub fn assert_trees(&self, holders: &[Holder]) { diff --git a/src/error.rs b/src/error.rs index ad8d92a4c..727383b97 100644 --- a/src/error.rs +++ b/src/error.rs @@ -304,10 +304,10 @@ pub enum Error { BlockNotFound(String), #[error("Block in slot {0} not found in database")] - SlotNotFound(u64), + BlockSlotNotFound(u64), - #[error("Slot checkpoint {0} not found in database")] - SlotCheckpointNotFound(u64), + #[error("Slot {0} not found in database")] + SlotNotFound(u64), #[error("Contract {0} not found in database")] ContractNotFound(String), diff --git a/src/runtime/import/util.rs b/src/runtime/import/util.rs index 5ad733427..cc1efe72b 100644 --- a/src/runtime/import/util.rs +++ b/src/runtime/import/util.rs @@ -170,22 +170,22 @@ pub(crate) fn get_verifying_slot_epoch(ctx: FunctionEnvMut) -> u64 { ctx.data().time_keeper.verifying_slot_epoch() } -/// Will return requested slot checkpoint from `SlotCheckpointStore`. -pub(crate) fn get_slot_checkpoint(ctx: FunctionEnvMut, slot: u64) -> i64 { +/// Will return requested slot from `SlotStore`. +pub(crate) fn get_slot(ctx: FunctionEnvMut, slot: u64) -> i64 { let env = ctx.data(); if env.contract_section != ContractSection::Deploy && env.contract_section != ContractSection::Exec && env.contract_section != ContractSection::Metadata { - error!(target: "runtime::db::db_get_slot_checkpoint()", "db_get_slot_checkpoint called in unauthorized section"); + error!(target: "runtime::db::db_get_slot()", "db_get_slot called in unauthorized section"); return CALLER_ACCESS_DENIED.into() } - let ret = match env.blockchain.lock().unwrap().slot_checkpoints.get(slot) { + let ret = match env.blockchain.lock().unwrap().slots.get(slot) { Ok(v) => v, Err(e) => { - error!(target: "runtime::db::db_get_slot_checkpoint()", "Internal error getting from slot checkpoints tree: {}", e); + error!(target: "runtime::db::db_get_slot()", "Internal error getting from slots tree: {}", e); return DB_GET_FAILED.into() } }; diff --git a/src/runtime/vm_runtime.rs b/src/runtime/vm_runtime.rs index def403b00..148c252c1 100644 --- a/src/runtime/vm_runtime.rs +++ b/src/runtime/vm_runtime.rs @@ -275,10 +275,10 @@ impl Runtime { import::util::get_verifying_slot_epoch, ), - "get_slot_checkpoint_" => Function::new_typed_with_env( + "get_slot_" => Function::new_typed_with_env( &mut store, &ctx, - import::util::get_slot_checkpoint, + import::util::get_slot, ), "get_blockchain_time_" => Function::new_typed_with_env( diff --git a/src/sdk/src/blockchain.rs b/src/sdk/src/blockchain.rs index 0a6ad3866..49b8962e6 100644 --- a/src/sdk/src/blockchain.rs +++ b/src/sdk/src/blockchain.rs @@ -21,9 +21,9 @@ use pasta_curves::{group::ff::Field, pallas}; /// Auxiliary structure used to keep track of slot validation parameters. #[derive(Debug, Clone, SerialEncodable, SerialDecodable)] -pub struct SlotCheckpoint { +pub struct Slot { /// Slot UID - pub slot: u64, + pub id: u64, /// Previous slot eta pub previous_eta: pallas::Base, /// Previous slot forks last proposal/block hashes, @@ -38,20 +38,20 @@ pub struct SlotCheckpoint { pub sigma2: pallas::Base, } -impl SlotCheckpoint { +impl Slot { pub fn new( - slot: u64, + id: u64, previous_eta: pallas::Base, fork_hashes: Vec, fork_previous_hashes: Vec, sigma1: pallas::Base, sigma2: pallas::Base, ) -> Self { - Self { slot, previous_eta, fork_hashes, fork_previous_hashes, sigma1, sigma2 } + Self { id, previous_eta, fork_hashes, fork_previous_hashes, sigma1, sigma2 } } - /// Generate the genesis slot checkpoint. - pub fn genesis_slot_checkpoint(genesis_block: blake3::Hash) -> Self { + /// Generate the genesis slot. + pub fn genesis_slot(genesis_block: blake3::Hash) -> Self { let previous_eta = pallas::Base::ZERO; let fork_hashes = vec![]; // Since genesis block has no previous, diff --git a/src/sdk/src/lib.rs b/src/sdk/src/lib.rs index 294bb9223..003478be6 100644 --- a/src/sdk/src/lib.rs +++ b/src/sdk/src/lib.rs @@ -23,7 +23,7 @@ pub use pasta_curves as pasta; /// Blockchain structures pub mod blockchain; -pub use blockchain::SlotCheckpoint; +pub use blockchain::Slot; /// Database functions pub mod db; diff --git a/src/sdk/src/util.rs b/src/sdk/src/util.rs index 4636798a5..d77fe2d8d 100644 --- a/src/sdk/src/util.rs +++ b/src/sdk/src/util.rs @@ -42,7 +42,7 @@ pub fn get_object_size(object_index: u32) -> i64 { unsafe { get_object_size_(object_index) } } -/// Auxiliary function to parse db_get and get_slot_checkpoint return value. +/// Auxiliary function to parse db_get and get_slot return value. pub(crate) fn parse_ret(ret: i64) -> GenericResult>> { if ret < 0 { match ret as i32 { @@ -99,13 +99,13 @@ pub fn get_verifying_slot_epoch() -> u64 { unsafe { get_verifying_slot_epoch_() } } -/// Everyone can call this. Will return requested slot checkpoint from `SlotCheckpointStore`. +/// Everyone can call this. Will return requested slot from `SlotStore`. /// /// ``` -/// slot_checkpoint = get_slot_checkpoint(slot); +/// slot = get_slot(slot); /// ``` -pub fn get_slot_checkpoint(slot: u64) -> GenericResult>> { - let ret = unsafe { get_slot_checkpoint_(slot) }; +pub fn get_slot(slot: u64) -> GenericResult>> { + let ret = unsafe { get_slot_(slot) }; parse_ret(ret) } @@ -128,6 +128,6 @@ extern "C" { fn get_current_slot_() -> u64; fn get_verifying_slot_() -> u64; fn get_verifying_slot_epoch_() -> u64; - fn get_slot_checkpoint_(slot: u64) -> i64; + fn get_slot_(slot: u64) -> i64; fn get_blockchain_time_() -> u64; } diff --git a/src/validator/mod.rs b/src/validator/mod.rs index 9c8eb1757..b20af4a27 100644 --- a/src/validator/mod.rs +++ b/src/validator/mod.rs @@ -20,7 +20,7 @@ use std::{collections::HashMap, io::Cursor}; use async_std::sync::{Arc, RwLock}; use darkfi_sdk::{ - blockchain::SlotCheckpoint, + blockchain::Slot, crypto::{PublicKey, CONSENSUS_CONTRACT_ID, DAO_CONTRACT_ID, MONEY_CONTRACT_ID}, pasta::pallas, }; @@ -172,23 +172,20 @@ impl Validator { // 2) When a transaction is being broadcasted to us // ========================== - /// Append to canonical state received finalized slot checkpoints from block sync task. - // TODO: integrate this to receive_blocks, as slot checkpoints will be part of received block. - pub async fn receive_slot_checkpoints( - &mut self, - slot_checkpoints: &[SlotCheckpoint], - ) -> Result<()> { - debug!(target: "validator", "receive_slot_checkpoints(): Appending slot checkpoints to ledger"); + /// Append to canonical state received finalized slots from block sync task. + // TODO: integrate this to receive_blocks, as slots will be part of received block. + pub async fn receive_slots(&mut self, slots: &[Slot]) -> Result<()> { + debug!(target: "validator", "receive_slots(): Appending slots to ledger"); let current_slot = self.consensus.time_keeper.current_slot(); let mut filtered = vec![]; - for slot_checkpoint in slot_checkpoints { - if slot_checkpoint.slot > current_slot { - warn!(target: "validator", "receive_slot_checkpoints(): Ignoring future slot checkpoint: {}", slot_checkpoint.slot); + for slot in slots { + if slot.id > current_slot { + warn!(target: "validator", "receive_slots(): Ignoring future slot: {}", slot.id); continue } - filtered.push(slot_checkpoint.clone()); + filtered.push(slot.clone()); } - self.blockchain.add_slot_checkpoints(&filtered[..])?; + self.blockchain.add_slots(&filtered[..])?; Ok(()) }