github.com/muhammedhassanm/blockchain@v0.0.0-20200120143007-697261defd4d/sawtooth-core-master/validator/src/state/merkle_ffi.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  use database::lmdb::LmdbDatabase;
    18  use state::error::StateDatabaseError;
    19  use state::merkle::*;
    20  /// This module contains all of the extern C functions for the Merkle trie
    21  use state::StateReader;
    22  use std::collections::HashMap;
    23  use std::ffi::CStr;
    24  use std::mem;
    25  use std::os::raw::{c_char, c_void};
    26  use std::slice;
    27  
    28  #[repr(u32)]
    29  #[derive(Debug)]
    30  pub enum ErrorCode {
    31      Success = 0,
    32      // Input errors
    33      NullPointerProvided = 1,
    34      InvalidHashString = 2,
    35      InvalidAddress = 3,
    36  
    37      // output errors
    38      DatabaseError = 0x11,
    39      NotFound = 0x12,
    40      InvalidChangeLogIndex = 0x13,
    41  
    42      StopIteration = 0xF0,
    43  
    44      Unknown = 0xFF,
    45  }
    46  
    47  #[repr(C)]
    48  #[derive(Debug)]
    49  pub struct Entry {
    50      address: *const c_char,
    51      data: *mut u8,
    52      data_len: usize,
    53  }
    54  
    55  #[no_mangle]
    56  pub extern "C" fn merkle_db_new(
    57      database: *const c_void,
    58      merkle_db: *mut *const c_void,
    59  ) -> ErrorCode {
    60      make_merkle_db(database, None, merkle_db)
    61  }
    62  
    63  #[no_mangle]
    64  pub extern "C" fn merkle_db_new_with_root(
    65      database: *const c_void,
    66      root: *const c_char,
    67      merkle_db: *mut *const c_void,
    68  ) -> ErrorCode {
    69      if root.is_null() {
    70          return ErrorCode::NullPointerProvided;
    71      }
    72  
    73      let state_root = unsafe {
    74          match CStr::from_ptr(root).to_str() {
    75              Ok(s) => Some(s),
    76              Err(_) => return ErrorCode::InvalidHashString,
    77          }
    78      };
    79  
    80      make_merkle_db(database, state_root, merkle_db)
    81  }
    82  
    83  fn make_merkle_db(
    84      database: *const c_void,
    85      root: Option<&str>,
    86      merkle_db: *mut *const c_void,
    87  ) -> ErrorCode {
    88      if database.is_null() {
    89          return ErrorCode::NullPointerProvided;
    90      }
    91  
    92      let db_ref = unsafe { (database as *const LmdbDatabase).as_ref().unwrap() };
    93      match MerkleDatabase::new(db_ref.clone(), root) {
    94          Ok(new_merkle_tree) => {
    95              unsafe {
    96                  *merkle_db = Box::into_raw(Box::new(new_merkle_tree)) as *const c_void;
    97              }
    98              ErrorCode::Success
    99          }
   100          Err(StateDatabaseError::DatabaseError(err)) => {
   101              error!("A Database Error occurred: {}", err);
   102              ErrorCode::DatabaseError
   103          }
   104          Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   105          Err(err) => {
   106              error!("Unknown Error!: {:?}", err);
   107              ErrorCode::Unknown
   108          }
   109      }
   110  }
   111  
   112  #[no_mangle]
   113  pub extern "C" fn merkle_db_drop(merkle_db: *mut c_void) -> ErrorCode {
   114      if merkle_db.is_null() {
   115          return ErrorCode::NullPointerProvided;
   116      }
   117  
   118      unsafe { Box::from_raw(merkle_db as *mut MerkleDatabase) };
   119      ErrorCode::Success
   120  }
   121  
   122  #[no_mangle]
   123  pub extern "C" fn merkle_db_get_merkle_root(
   124      merkle_db: *mut c_void,
   125      merkle_root: *mut *const u8,
   126      merkle_root_len: *mut usize,
   127  ) -> ErrorCode {
   128      if merkle_db.is_null() {
   129          return ErrorCode::NullPointerProvided;
   130      }
   131  
   132      unsafe {
   133          let state_root = (*(merkle_db as *mut MerkleDatabase)).get_merkle_root();
   134          *merkle_root = state_root.as_ptr();
   135          *merkle_root_len = state_root.as_bytes().len();
   136  
   137          mem::forget(state_root);
   138  
   139          ErrorCode::Success
   140      }
   141  }
   142  
   143  #[no_mangle]
   144  pub extern "C" fn merkle_db_set_merkle_root(
   145      merkle_db: *mut c_void,
   146      root: *const c_char,
   147  ) -> ErrorCode {
   148      if merkle_db.is_null() {
   149          return ErrorCode::NullPointerProvided;
   150      }
   151      if root.is_null() {
   152          return ErrorCode::NullPointerProvided;
   153      }
   154  
   155      let state_root = unsafe {
   156          match CStr::from_ptr(root).to_str() {
   157              Ok(s) => s,
   158              Err(_) => return ErrorCode::InvalidHashString,
   159          }
   160      };
   161  
   162      match unsafe { (*(merkle_db as *mut MerkleDatabase)).set_merkle_root(state_root) } {
   163          Ok(()) => ErrorCode::Success,
   164          Err(StateDatabaseError::DatabaseError(err)) => {
   165              error!("A Database Error occurred: {}", err);
   166              ErrorCode::DatabaseError
   167          }
   168          Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   169          Err(err) => {
   170              error!("Unknown Error!: {:?}", err);
   171              ErrorCode::Unknown
   172          }
   173      }
   174  }
   175  
   176  #[no_mangle]
   177  /// Returns ErrorCode.Success if the address is contained, error otherwise.
   178  /// Most likely, this error is ErrorCode.NotFound
   179  pub extern "C" fn merkle_db_contains(merkle_db: *mut c_void, address: *const c_char) -> ErrorCode {
   180      if merkle_db.is_null() {
   181          return ErrorCode::NullPointerProvided;
   182      }
   183      if address.is_null() {
   184          return ErrorCode::NullPointerProvided;
   185      }
   186  
   187      let address_str = unsafe {
   188          match CStr::from_ptr(address).to_str() {
   189              Ok(s) => s,
   190              Err(_) => return ErrorCode::InvalidAddress,
   191          }
   192      };
   193  
   194      unsafe {
   195          match (*(merkle_db as *mut MerkleDatabase)).contains(address_str) {
   196              Ok(true) => ErrorCode::Success,
   197              Ok(false) => ErrorCode::NotFound,
   198              Err(StateDatabaseError::DatabaseError(err)) => {
   199                  error!("A Database Error occurred: {}", err);
   200                  ErrorCode::DatabaseError
   201              }
   202              Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   203              Err(err) => {
   204                  error!("Unknown Error!: {:?}", err);
   205                  ErrorCode::Unknown
   206              }
   207          }
   208      }
   209  }
   210  
   211  #[no_mangle]
   212  pub extern "C" fn merkle_db_get(
   213      merkle_db: *mut c_void,
   214      address: *const c_char,
   215      bytes: *mut *const u8,
   216      bytes_len: *mut usize,
   217  ) -> ErrorCode {
   218      if merkle_db.is_null() {
   219          return ErrorCode::NullPointerProvided;
   220      }
   221      if address.is_null() {
   222          return ErrorCode::NullPointerProvided;
   223      }
   224  
   225      let address_str = unsafe {
   226          match CStr::from_ptr(address).to_str() {
   227              Ok(s) => s,
   228              Err(_) => return ErrorCode::InvalidAddress,
   229          }
   230      };
   231  
   232      unsafe {
   233          match (*(merkle_db as *mut MerkleDatabase)).get(address_str) {
   234              Ok(Some(data_vec)) => {
   235                  let data = data_vec.into_boxed_slice();
   236                  *bytes_len = data.len();
   237                  *bytes = data.as_ptr();
   238  
   239                  // It will be up to the callee to cleanup this memory
   240                  mem::forget(data);
   241  
   242                  ErrorCode::Success
   243              }
   244              Ok(None) => ErrorCode::NotFound,
   245              Err(StateDatabaseError::DatabaseError(err)) => {
   246                  error!("A Database Error occurred: {}", err);
   247                  ErrorCode::DatabaseError
   248              }
   249              Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   250              Err(err) => {
   251                  error!("Unknown Error!: {:?}", err);
   252                  ErrorCode::Unknown
   253              }
   254          }
   255      }
   256  }
   257  
   258  #[no_mangle]
   259  pub extern "C" fn merkle_db_set(
   260      merkle_db: *mut c_void,
   261      address: *const c_char,
   262      data: *const u8,
   263      data_len: usize,
   264      merkle_root: *mut *const u8,
   265      merkle_root_len: *mut usize,
   266  ) -> ErrorCode {
   267      if merkle_db.is_null() {
   268          return ErrorCode::NullPointerProvided;
   269      }
   270      if address.is_null() {
   271          return ErrorCode::NullPointerProvided;
   272      }
   273  
   274      if data.is_null() {
   275          return ErrorCode::NullPointerProvided;
   276      }
   277  
   278      let address_str = unsafe {
   279          match CStr::from_ptr(address).to_str() {
   280              Ok(s) => s,
   281              Err(_) => return ErrorCode::InvalidHashString,
   282          }
   283      };
   284  
   285      let data = unsafe { slice::from_raw_parts(data, data_len) };
   286  
   287      unsafe {
   288          match (*(merkle_db as *mut MerkleDatabase)).set(address_str, data) {
   289              Ok(state_root) => {
   290                  *merkle_root = state_root.as_ptr();
   291                  *merkle_root_len = state_root.as_bytes().len();
   292  
   293                  mem::forget(state_root);
   294  
   295                  ErrorCode::Success
   296              }
   297              Err(StateDatabaseError::DatabaseError(err)) => {
   298                  error!("A Database Error occurred: {}", err);
   299                  ErrorCode::DatabaseError
   300              }
   301              Err(err) => {
   302                  error!("Unknown Error!: {:?}", err);
   303                  ErrorCode::Unknown
   304              }
   305          }
   306      }
   307  }
   308  
   309  #[no_mangle]
   310  pub extern "C" fn merkle_db_delete(
   311      merkle_db: *mut c_void,
   312      address: *const c_char,
   313      merkle_root: *mut *const u8,
   314      merkle_root_len: *mut usize,
   315  ) -> ErrorCode {
   316      if merkle_db.is_null() {
   317          return ErrorCode::NullPointerProvided;
   318      }
   319      if address.is_null() {
   320          return ErrorCode::NullPointerProvided;
   321      }
   322  
   323      let address_str = unsafe {
   324          match CStr::from_ptr(address).to_str() {
   325              Ok(s) => s,
   326              Err(_) => return ErrorCode::InvalidHashString,
   327          }
   328      };
   329  
   330      unsafe {
   331          match (*(merkle_db as *mut MerkleDatabase)).delete(address_str) {
   332              Ok(state_root) => {
   333                  *merkle_root = state_root.as_ptr();
   334                  *merkle_root_len = state_root.as_bytes().len();
   335  
   336                  mem::forget(state_root);
   337  
   338                  ErrorCode::Success
   339              }
   340              Err(StateDatabaseError::DatabaseError(err)) => {
   341                  error!("A Database Error occurred: {}", err);
   342                  ErrorCode::DatabaseError
   343              }
   344              Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   345              Err(err) => {
   346                  error!("Unknown Error!: {:?}", err);
   347                  ErrorCode::Unknown
   348              }
   349          }
   350      }
   351  }
   352  
   353  #[no_mangle]
   354  pub extern "C" fn merkle_db_update(
   355      merkle_db: *mut c_void,
   356      updates: *const *const c_void,
   357      updates_len: usize,
   358      deletes: *const *const c_char,
   359      deletes_len: usize,
   360      virtual_write: bool,
   361      merkle_root: *mut *const u8,
   362      merkle_root_len: *mut usize,
   363  ) -> ErrorCode {
   364      if merkle_db.is_null() {
   365          return ErrorCode::NullPointerProvided;
   366      }
   367  
   368      if updates_len > 0 && updates.is_null() {
   369          return ErrorCode::NullPointerProvided;
   370      }
   371  
   372      if deletes_len > 0 && deletes.is_null() {
   373          return ErrorCode::NullPointerProvided;
   374      }
   375  
   376      let update_map: HashMap<String, Vec<u8>> = {
   377          let update_vec: Result<Vec<(String, Vec<u8>)>, ErrorCode> = if updates_len > 0 {
   378              unsafe { slice::from_raw_parts(updates, updates_len) }
   379                  .iter()
   380                  .map(|ptr| unsafe {
   381                      let entry = *ptr as *const Entry;
   382                      let address = match CStr::from_ptr((*entry).address).to_str() {
   383                          Ok(s) => String::from(s),
   384                          Err(_) => return Err(ErrorCode::InvalidAddress),
   385                      };
   386                      let data = slice::from_raw_parts((*entry).data, (*entry).data_len);
   387  
   388                      let data = Vec::from(data);
   389                      Ok((address, data))
   390                  })
   391                  .collect()
   392          } else {
   393              Ok(Vec::with_capacity(0))
   394          };
   395  
   396          if update_vec.is_err() {
   397              return update_vec.unwrap_err();
   398          }
   399  
   400          update_vec.unwrap().into_iter().collect()
   401      };
   402  
   403      let deletes: Result<Vec<String>, ErrorCode> = if deletes_len > 0 {
   404          unsafe { slice::from_raw_parts(deletes, deletes_len) }
   405              .iter()
   406              .map(|c_str| {
   407                  unsafe { CStr::from_ptr(*c_str).to_str() }
   408                      .map(String::from)
   409                      .map_err(|_| ErrorCode::InvalidAddress)
   410              })
   411              .collect()
   412      } else {
   413          Ok(Vec::with_capacity(0))
   414      };
   415  
   416      if deletes.is_err() {
   417          return deletes.unwrap_err();
   418      }
   419  
   420      unsafe {
   421          match (*(merkle_db as *mut MerkleDatabase)).update(
   422              &update_map,
   423              &deletes.unwrap(),
   424              virtual_write,
   425          ) {
   426              Ok(state_root) => {
   427                  *merkle_root = state_root.as_ptr();
   428                  *merkle_root_len = state_root.as_bytes().len();
   429  
   430                  mem::forget(state_root);
   431  
   432                  ErrorCode::Success
   433              }
   434              Err(StateDatabaseError::DatabaseError(err)) => {
   435                  error!("A Database Error occurred: {}", err);
   436                  ErrorCode::DatabaseError
   437              }
   438              Err(err) => {
   439                  error!("Unknown Error!: {:?}", err);
   440                  ErrorCode::Unknown
   441              }
   442          }
   443      }
   444  }
   445  
   446  #[no_mangle]
   447  pub extern "C" fn merkle_db_prune(
   448      state_database: *mut c_void,
   449      root: *const c_char,
   450      result: *mut bool,
   451  ) -> ErrorCode {
   452      if state_database.is_null() {
   453          return ErrorCode::NullPointerProvided;
   454      }
   455      if root.is_null() {
   456          return ErrorCode::NullPointerProvided;
   457      }
   458  
   459      let state_root = unsafe {
   460          match CStr::from_ptr(root).to_str() {
   461              Ok(s) => s,
   462              Err(_) => return ErrorCode::InvalidHashString,
   463          }
   464      };
   465  
   466      let db_ref = unsafe { (state_database as *const LmdbDatabase).as_ref().unwrap() };
   467  
   468      match MerkleDatabase::prune(db_ref, &state_root) {
   469          Ok(results) => {
   470              unsafe {
   471                  *result = !results.is_empty();
   472              }
   473              ErrorCode::Success
   474          }
   475          Err(StateDatabaseError::InvalidHash(_)) => ErrorCode::InvalidHashString,
   476          Err(StateDatabaseError::InvalidChangeLogIndex(msg)) => {
   477              error!(
   478                  "Invalid Change Log Index while pruning {}: {}",
   479                  state_root, msg
   480              );
   481              ErrorCode::InvalidChangeLogIndex
   482          }
   483          Err(StateDatabaseError::DatabaseError(err)) => {
   484              error!("A Database Error occurred: {}", err);
   485              ErrorCode::DatabaseError
   486          }
   487          Err(err) => {
   488              error!("Unknown Error!: {:?}", err);
   489              ErrorCode::Unknown
   490          }
   491      }
   492  }
   493  
   494  #[no_mangle]
   495  pub extern "C" fn merkle_db_leaf_iterator_new(
   496      merkle_db: *mut c_void,
   497      prefix: *const c_char,
   498      iterator: *mut *const c_void,
   499  ) -> ErrorCode {
   500      if merkle_db.is_null() {
   501          return ErrorCode::NullPointerProvided;
   502      }
   503  
   504      if prefix.is_null() {
   505          return ErrorCode::NullPointerProvided;
   506      }
   507  
   508      let prefix = unsafe {
   509          match CStr::from_ptr(prefix).to_str() {
   510              Ok(s) => s,
   511              Err(_) => return ErrorCode::InvalidAddress,
   512          }
   513      };
   514  
   515      match unsafe { (*(merkle_db as *mut MerkleDatabase)).leaves(Some(prefix)) } {
   516          Ok(leaf_iterator) => {
   517              unsafe {
   518                  *iterator = Box::into_raw(leaf_iterator) as *const c_void;
   519              }
   520  
   521              ErrorCode::Success
   522          }
   523          Err(StateDatabaseError::DatabaseError(err)) => {
   524              error!("A Database Error occurred: {}", err);
   525              ErrorCode::DatabaseError
   526          }
   527          Err(StateDatabaseError::NotFound(_)) => ErrorCode::NotFound,
   528          Err(err) => {
   529              error!("Unknown Error!: {:?}", err);
   530              ErrorCode::Unknown
   531          }
   532      }
   533  }
   534  
   535  #[no_mangle]
   536  pub extern "C" fn merkle_db_leaf_iterator_drop(iterator: *mut c_void) -> ErrorCode {
   537      if iterator.is_null() {
   538          return ErrorCode::NullPointerProvided;
   539      }
   540  
   541      unsafe { Box::from_raw(iterator as *mut MerkleLeafIterator) };
   542      ErrorCode::Success
   543  }
   544  
   545  #[no_mangle]
   546  pub extern "C" fn merkle_db_leaf_iterator_next(
   547      iterator: *mut c_void,
   548      address: *mut *const u8,
   549      address_len: *mut usize,
   550      bytes: *mut *const u8,
   551      bytes_len: *mut usize,
   552  ) -> ErrorCode {
   553      if iterator.is_null() {
   554          return ErrorCode::NullPointerProvided;
   555      }
   556  
   557      match unsafe { (*(iterator as *mut MerkleLeafIterator)).next() } {
   558          Some(Ok((entry_addr, entry_bytes))) => unsafe {
   559              let address_bytes = entry_addr.into_bytes().into_boxed_slice();
   560              *address_len = address_bytes.len();
   561              *address = address_bytes.as_ptr();
   562  
   563              let data = entry_bytes.into_boxed_slice();
   564              *bytes_len = data.len();
   565              *bytes = data.as_ptr();
   566  
   567              mem::forget(address_bytes);
   568              mem::forget(data);
   569  
   570              ErrorCode::Success
   571          },
   572          None => ErrorCode::StopIteration,
   573          Some(Err(StateDatabaseError::DatabaseError(err))) => {
   574              error!("A Database Error occurred: {}", err);
   575              ErrorCode::DatabaseError
   576          }
   577          Some(Err(err)) => {
   578              error!("Unknown Error!: {:?}", err);
   579              ErrorCode::Unknown
   580          }
   581      }
   582  }