github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/sdk/rust/src/consensus/engine.rs (about)

     1  /*
     2   * Copyright 2018 Intel Corporation
     3   *
     4   * Licensed under the Apache License, Version 2.0 (the "License");
     5   * you may not use this file except in compliance with the License.
     6   * You may obtain a copy of the License at
     7   *
     8   *     http://www.apache.org/licenses/LICENSE-2.0
     9   *
    10   * Unless required by applicable law or agreed to in writing, software
    11   * distributed under the License is distributed on an "AS IS" BASIS,
    12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13   * See the License for the specific language governing permissions and
    14   * limitations under the License.
    15   * ------------------------------------------------------------------------------
    16   */
    17  
    18  use std::error;
    19  use std::fmt;
    20  use std::ops::Deref;
    21  use std::sync::mpsc::Receiver;
    22  
    23  use hex;
    24  
    25  use consensus::service::Service;
    26  
    27  /// An update from the validator
    28  #[derive(Debug)]
    29  pub enum Update {
    30      PeerConnected(PeerInfo),
    31      PeerDisconnected(PeerId),
    32      PeerMessage(PeerMessage, PeerId),
    33      BlockNew(Block),
    34      BlockValid(BlockId),
    35      BlockInvalid(BlockId),
    36      BlockCommit(BlockId),
    37      Shutdown,
    38  }
    39  
    40  #[derive(Clone, Default, Eq, Hash, PartialEq, PartialOrd)]
    41  pub struct BlockId(Vec<u8>);
    42  impl Deref for BlockId {
    43      type Target = Vec<u8>;
    44  
    45      fn deref(&self) -> &Vec<u8> {
    46          &self.0
    47      }
    48  }
    49  impl From<BlockId> for Vec<u8> {
    50      fn from(id: BlockId) -> Vec<u8> {
    51          id.0
    52      }
    53  }
    54  impl From<Vec<u8>> for BlockId {
    55      fn from(v: Vec<u8>) -> BlockId {
    56          BlockId(v)
    57      }
    58  }
    59  impl AsRef<[u8]> for BlockId {
    60      fn as_ref(&self) -> &[u8] {
    61          &self.0
    62      }
    63  }
    64  impl fmt::Debug for BlockId {
    65      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    66          write!(f, "{}", hex::encode(&self.0))
    67      }
    68  }
    69  
    70  /// All information about a block that is relevant to consensus
    71  #[derive(Clone, Default)]
    72  pub struct Block {
    73      pub block_id: BlockId,
    74      pub previous_id: BlockId,
    75      pub signer_id: PeerId,
    76      pub block_num: u64,
    77      pub payload: Vec<u8>,
    78      pub summary: Vec<u8>,
    79  }
    80  impl fmt::Debug for Block {
    81      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    82          write!(
    83              f,
    84              "Block(block_num: {:?}, block_id: {:?}, previous_id: {:?}, signer_id: {:?}, payload: {}, summary: {})",
    85              self.block_num,
    86              self.block_id,
    87              self.previous_id,
    88              self.signer_id,
    89              hex::encode(&self.payload),
    90              hex::encode(&self.summary),
    91          )
    92      }
    93  }
    94  
    95  #[derive(Clone, Default, PartialEq, Eq, Hash, PartialOrd)]
    96  pub struct PeerId(Vec<u8>);
    97  impl Deref for PeerId {
    98      type Target = Vec<u8>;
    99  
   100      fn deref(&self) -> &Vec<u8> {
   101          &self.0
   102      }
   103  }
   104  impl From<PeerId> for Vec<u8> {
   105      fn from(id: PeerId) -> Vec<u8> {
   106          id.0
   107      }
   108  }
   109  impl From<Vec<u8>> for PeerId {
   110      fn from(v: Vec<u8>) -> PeerId {
   111          PeerId(v)
   112      }
   113  }
   114  impl AsRef<[u8]> for PeerId {
   115      fn as_ref(&self) -> &[u8] {
   116          &self.0
   117      }
   118  }
   119  impl fmt::Debug for PeerId {
   120      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   121          write!(f, "{}", hex::encode(&self.0))
   122      }
   123  }
   124  
   125  /// Information about a peer that is relevant to consensus
   126  #[derive(Default, Debug)]
   127  pub struct PeerInfo {
   128      pub peer_id: PeerId,
   129  }
   130  
   131  /// A consensus-related message sent between peers
   132  #[derive(Default, Debug)]
   133  pub struct PeerMessage {
   134      pub message_type: String,
   135      pub content: Vec<u8>,
   136  }
   137  
   138  /// Engine is the only trait that needs to be implemented when adding a new consensus engine.
   139  ///
   140  /// The consensus engine should listen for notifications from the validator about the status of
   141  /// blocks and messages from peers. It must also determine internally when to build and publish
   142  /// blocks based on its view of the network and the consensus algorithm it implements. Often this
   143  /// will be some sort of timer-based interrupt.
   144  ///
   145  /// Based on the updates the engine receives through the `Receiver<Update>` and the specifics of
   146  /// the algorithm being implemented, the engine utilizes the provided `Service` to create new
   147  /// blocks, communicate with its peers, request that certain blocks be committed, and fail or
   148  /// ignore blocks that should not be committed.
   149  ///
   150  /// While the validator may take actions beyond what the engine instructs it to do for performance
   151  /// optimization reasons, it is the consensus engine's responsibility to drive the progress of the
   152  /// validator and ensure liveness.
   153  ///
   154  /// It is not the engine's responsibility to manage blocks or memory, other than to ensure it
   155  /// responds to every new block with a commit, fail, or ignore within a "reasonable amount of
   156  /// time". The validator is responsible for guaranteeing the integrity of all blocks sent to the
   157  /// engine until the engine responds. After the engine responds, the validator does not guarantee
   158  /// that the block and its predecessors continue to be available unless the block was committed.
   159  ///
   160  /// Finally, as an optimization, the consensus engine can send prioritized lists of blocks to the
   161  /// chain controller for checking instead of sending them one at a time, which allows the chain
   162  /// controller to intelligently work ahead while the consensus engine makes its decisions.
   163  pub trait Engine {
   164      /// Called after the engine is initialized, when a connection to the validator has been
   165      /// established. Notifications from the validator are sent along `updates`. `service` is used
   166      /// to send requests to the validator.
   167      fn start(
   168          &mut self,
   169          updates: Receiver<Update>,
   170          service: Box<Service>,
   171          startup_state: StartupState,
   172      );
   173  
   174      /// Get the version of this engine
   175      fn version(&self) -> String;
   176  
   177      /// Get the name of the engine, typically the algorithm being implemented
   178      fn name(&self) -> String;
   179  }
   180  
   181  /// State provided to an engine when it is started
   182  #[derive(Debug, Default)]
   183  pub struct StartupState {
   184      pub chain_head: Block,
   185      pub peers: Vec<PeerInfo>,
   186      pub local_peer_info: PeerInfo,
   187  }
   188  
   189  #[derive(Debug)]
   190  pub enum Error {
   191      EncodingError(String),
   192      SendError(String),
   193      ReceiveError(String),
   194      InvalidState(String),
   195      UnknownBlock(String),
   196      UnknownPeer(String),
   197      NoChainHead,
   198      BlockNotReady,
   199  }
   200  
   201  impl error::Error for Error {
   202      fn description(&self) -> &str {
   203          use self::Error::*;
   204          match *self {
   205              EncodingError(ref s) => s,
   206              SendError(ref s) => s,
   207              ReceiveError(ref s) => s,
   208              InvalidState(ref s) => s,
   209              UnknownBlock(ref s) => s,
   210              UnknownPeer(ref s) => s,
   211              NoChainHead => "No chain head",
   212              BlockNotReady => "Block not ready to finalize",
   213          }
   214      }
   215  
   216      fn cause(&self) -> Option<&error::Error> {
   217          use self::Error::*;
   218          match *self {
   219              EncodingError(_) => None,
   220              SendError(_) => None,
   221              ReceiveError(_) => None,
   222              InvalidState(_) => None,
   223              UnknownBlock(_) => None,
   224              UnknownPeer(_) => None,
   225              NoChainHead => None,
   226              BlockNotReady => None,
   227          }
   228      }
   229  }
   230  
   231  impl fmt::Display for Error {
   232      fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
   233          use self::Error::*;
   234          match *self {
   235              EncodingError(ref s) => write!(f, "EncodingError: {}", s),
   236              SendError(ref s) => write!(f, "SendError: {}", s),
   237              ReceiveError(ref s) => write!(f, "ReceiveError: {}", s),
   238              InvalidState(ref s) => write!(f, "InvalidState: {}", s),
   239              UnknownBlock(ref s) => write!(f, "UnknownBlock: {}", s),
   240              UnknownPeer(ref s) => write!(f, "UnknownPeer: {}", s),
   241              NoChainHead => write!(f, "NoChainHead"),
   242              BlockNotReady => write!(f, "BlockNotReady"),
   243          }
   244      }
   245  }
   246  
   247  #[cfg(test)]
   248  pub mod tests {
   249      use super::*;
   250  
   251      use std::default::Default;
   252      use std::sync::mpsc::{channel, RecvTimeoutError};
   253      use std::sync::{Arc, Mutex};
   254      use std::thread;
   255      use std::time::Duration;
   256  
   257      use consensus::service::tests::MockService;
   258  
   259      pub struct MockEngine {
   260          calls: Arc<Mutex<Vec<String>>>,
   261      }
   262  
   263      impl MockEngine {
   264          pub fn new() -> Self {
   265              MockEngine {
   266                  calls: Arc::new(Mutex::new(Vec::new())),
   267              }
   268          }
   269  
   270          pub fn with(amv: Arc<Mutex<Vec<String>>>) -> Self {
   271              MockEngine { calls: amv }
   272          }
   273  
   274          pub fn calls(&self) -> Vec<String> {
   275              let calls = self.calls.lock().unwrap();
   276              let mut v = Vec::with_capacity((*calls).len());
   277              v.clone_from(&*calls);
   278              v
   279          }
   280      }
   281  
   282      impl Engine for MockEngine {
   283          fn start(
   284              &mut self,
   285              updates: Receiver<Update>,
   286              _service: Box<Service>,
   287              _startup_state: StartupState,
   288          ) {
   289              (*self.calls.lock().unwrap()).push("start".into());
   290              loop {
   291                  match updates.recv_timeout(Duration::from_millis(100)) {
   292                      Ok(update) => {
   293                          // We don't check for exit() here because we want to drain all the updates
   294                          // before we exit. In a real implementation, exit() should also be checked
   295                          // here since there is no guarantee the queue will ever be empty.
   296                          match update {
   297                              Update::PeerConnected(_) => {
   298                                  (*self.calls.lock().unwrap()).push("PeerConnected".into())
   299                              }
   300                              Update::PeerDisconnected(_) => {
   301                                  (*self.calls.lock().unwrap()).push("PeerDisconnected".into())
   302                              }
   303                              Update::PeerMessage(_, _) => {
   304                                  (*self.calls.lock().unwrap()).push("PeerMessage".into())
   305                              }
   306                              Update::BlockNew(_) => {
   307                                  (*self.calls.lock().unwrap()).push("BlockNew".into())
   308                              }
   309                              Update::BlockValid(_) => {
   310                                  (*self.calls.lock().unwrap()).push("BlockValid".into())
   311                              }
   312                              Update::BlockInvalid(_) => {
   313                                  (*self.calls.lock().unwrap()).push("BlockInvalid".into())
   314                              }
   315                              Update::BlockCommit(_) => {
   316                                  (*self.calls.lock().unwrap()).push("BlockCommit".into())
   317                              }
   318                              Update::Shutdown => {
   319                                  println!("shutdown");
   320                                  break;
   321                              }
   322                          };
   323                      }
   324                      Err(RecvTimeoutError::Disconnected) => {
   325                          println!("disconnected");
   326                          break;
   327                      }
   328                      Err(RecvTimeoutError::Timeout) => {
   329                          println!("timeout");
   330                      }
   331                  }
   332              }
   333          }
   334          fn version(&self) -> String {
   335              "0".into()
   336          }
   337          fn name(&self) -> String {
   338              "mock".into()
   339          }
   340      }
   341  
   342      #[test]
   343      fn test_engine() {
   344          // Create the mock engine with this vec so we can refer to it later. Once we put the engine
   345          // in a box, it is hard to get the vec back out.
   346          let calls = Arc::new(Mutex::new(Vec::new()));
   347  
   348          // We are going to run two threads to simulate the validator and the driver
   349          let mut mock_engine = MockEngine::with(calls.clone());
   350  
   351          let (sender, receiver) = channel();
   352          sender
   353              .send(Update::PeerConnected(Default::default()))
   354              .unwrap();
   355          sender
   356              .send(Update::PeerDisconnected(Default::default()))
   357              .unwrap();
   358          sender
   359              .send(Update::PeerMessage(Default::default(), Default::default()))
   360              .unwrap();
   361          sender.send(Update::BlockNew(Default::default())).unwrap();
   362          sender.send(Update::BlockValid(Default::default())).unwrap();
   363          sender
   364              .send(Update::BlockInvalid(Default::default()))
   365              .unwrap();
   366          sender
   367              .send(Update::BlockCommit(Default::default()))
   368              .unwrap();
   369          let handle = thread::spawn(move || {
   370              let svc = Box::new(MockService {});
   371              mock_engine.start(receiver, svc, Default::default());
   372          });
   373          sender.send(Update::Shutdown).unwrap();
   374          handle.join().unwrap();
   375          assert!(contains(&calls, "start"));
   376          assert!(contains(&calls, "PeerConnected"));
   377          assert!(contains(&calls, "PeerDisconnected"));
   378          assert!(contains(&calls, "PeerMessage"));
   379          assert!(contains(&calls, "BlockNew"));
   380          assert!(contains(&calls, "BlockValid"));
   381          assert!(contains(&calls, "BlockInvalid"));
   382          assert!(contains(&calls, "BlockCommit"));
   383      }
   384  
   385      fn contains(calls: &Arc<Mutex<Vec<String>>>, expected: &str) -> bool {
   386          for call in &*(calls.lock().unwrap()) {
   387              if expected == call {
   388                  return true;
   389              }
   390          }
   391          false
   392      }
   393  }