Search code examples
rustblockchainbitcoinrocksdb

How to convert 'struct' to a stream of data?


I want to save a struct as a value in RocksDB and to do that, I want to codificate the Struct as a sequence of characters.

I know that is possible to convert to 'u8' using 'any_as_u8_slice' (meshopt crate), but I don't find nothing to revert the conversion.

How could I convert the Struct in a sequence of characters that I could revert after?

Here are a peace of code:

fn main() {
let path = Path::new("/home/ubuntu/.bitcoin");
let dbB = BitcoinDB::new(path, true).unwrap();
let path = "/home/ubuntu/.rocksdb";
let db = DB::open_default(path).unwrap();
let m = 0;
let n = 2000;

for block in dbB.iter_block::<SBlock>(m, n) {
    for tx in block.txdata {
        //db.put(key, tx).unwrap();
    }
}

}

The idea is codificate 'tx', to add as part of the value in RocksDB.

I want to do this for improve the performance of getting a tx in the blockchain, adding indexes to the database. But just for range of blocks between 'm' and 'n'.

For iterate the blocks in the blockchain I am using the following crate: https://crates.io/crates/bitcoin-explorer, so the 'tx' struct is already created.


Solution

  • If and only if the original structs derived Serialize and Deserialize traits, then you could use bincode to serialize them into binary-encoded Vec<u8>.

    Here I have a tuple struct MyStruct wrapped the original struct StructFromAnotherTool and use hex to encode and decode the result from Vec<u8> to and from hex string so I could easily store the hex string representation in a database. Note that the structs derive PartialEq and Debug for an assertion in the end:

    use serde::{Deserialize, Serialize};
    use hex;
    
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct StructFromOtherTool {
        x: f32,
        y: f32,
    }
    
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct MyStruct(StructFromOtherTool);
    
    fn main() { 
        let mystruct = MyStruct(SomeStruct { x: 1.3, y: 5.2 });
    
        let encoded: Vec<u8> = bincode::serialize(&mystruct).unwrap();
    
        // This hex string representation can be stored in a database.        
        let s = hex::encode(encoded.clone());
    
        println!("Hex encoded struct: {}", s);
    
        // We then decode the hex string and use bincode to deserialize back to a MyStruct entity.
        let v = hex::decode(s).unwrap();
    
        let decoded = bincode::deserialize(&v[..]).unwrap();
    
        assert_eq!(mystruct, decoded);
    }