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 }