6 using SQLite.Net.Attributes;
7 using SQLite.Net.Interop;
8 using SQLite.Net.Platform.Generic;
12 [Table("BlockStorage")]
16 /// Item ID in the database
18 [PrimaryKey, AutoIncrement]
19 public int ItemID { get; set; }
22 /// PBKDF2+Salsa20 of block hash
25 public byte[] ScryptHash { get; set; }
28 /// Serialized representation of block header
30 public byte[] BlockHeader { get; set; }
33 /// Block position in file
35 public long nBlockPos { get; set; }
38 /// Block size in bytes
40 public int nBlockSize { get; set; }
43 public class CBlockStore : IDisposable
45 private bool disposed = false;
46 private object LockObj = new object();
47 private SQLiteConnection dbConn = null;
50 /// Init the block storage manager.
52 /// <param name="IndexDB">Path to index database</param>
53 /// <param name="BlockFile">Path to block file</param>
54 public CBlockStore(string IndexDB = "blockstore.dat", string BlockFile = "blk0001.dat")
56 bool firstInit = !File.Exists(IndexDB);
57 dbConn = new SQLiteConnection(new SQLitePlatformGeneric(), IndexDB);
63 dbConn.CreateTable<CBlockStoreItem>(CreateFlags.AutoIncPK);
68 public bool ParseBlockFile(string BlockFile = "bootstrap.dat")
70 // TODO: Rewrite completely.
72 var QueryGet = dbConn.Query<CBlockStoreItem>("select * from [BlockStorage] order by [ItemId] desc limit 1");
76 if (QueryGet.Count() == 1)
78 var res = QueryGet.First();
79 nOffset = res.nBlockPos + res.nBlockSize;
82 var fileReader = new BinaryReader(File.OpenRead(BlockFile));
83 var fileStream = fileReader.BaseStream;
85 var buffer = new byte[1000000]; // Max block size is 1Mb
86 var intBuffer = new byte[4];
88 fileStream.Seek(nOffset, SeekOrigin.Begin); // Seek to previous offset + previous block length
90 dbConn.BeginTransaction();
92 while (fileStream.Read(buffer, 0, 4) == 4) // Read magic number
94 var nMagic = BitConverter.ToUInt32(buffer, 0);
95 if (nMagic != 0xe5e9e8e4)
97 Console.WriteLine("Incorrect magic number.");
101 var nBytesRead = fileStream.Read(buffer, 0, 4);
104 Console.WriteLine("BLKSZ EOF");
108 var nBlockSize = BitConverter.ToInt32(buffer, 0);
110 nOffset = fileStream.Position;
112 nBytesRead = fileStream.Read(buffer, 0, nBlockSize);
114 if (nBytesRead == 0 || nBytesRead != nBlockSize)
116 Console.WriteLine("BLK EOF");
120 var block = new CBlock(buffer);
122 if (nOffset % 1000 == 0) // Commit on each 1000th block
124 Console.WriteLine("Offset={0}, Hash: {1}", nOffset, block.header.Hash.ToString());
126 dbConn.BeginTransaction();
129 var result = dbConn.Insert(new CBlockStoreItem()
131 ScryptHash = block.header.Hash,
132 BlockHeader = block.header,
134 nBlockSize = nBlockSize
140 fileReader.Dispose();
150 public void Dispose()
153 GC.SuppressFinalize(this);
156 protected virtual void Dispose(bool disposing)
162 // Free other state (managed objects).