コード例 #1
0
ファイル: RocksDBStore.cs プロジェクト: x86chi/libplanet
        /// <inheritdoc/>
        public override IEnumerable <Tuple <HashDigest <SHA256>, long> > IterateStateReferences(
            Guid chainId,
            string key,
            long?highestIndex,
            long?lowestIndex,
            int?limit)
        {
            highestIndex ??= long.MaxValue;
            lowestIndex ??= 0;
            limit ??= int.MaxValue;

            if (highestIndex < lowestIndex)
            {
                var message =
                    $"highestIndex({highestIndex}) must be greater than or equal to " +
                    $"lowestIndex({lowestIndex})";
                throw new ArgumentException(
                          message,
                          nameof(highestIndex));
            }

            byte[] keyBytes = RocksDBStoreBitConverter.GetBytes(key);
            byte[] prefix   = StateRefKeyPrefix.Concat(keyBytes).ToArray();

            return(IterateStateReferences(
                       chainId, prefix, highestIndex.Value, lowestIndex.Value, limit.Value));
        }
コード例 #2
0
        /// <inheritdoc cref="BaseStore.AppendIndex(Guid, BlockHash)"/>
        public override long AppendIndex(Guid chainId, BlockHash hash)
        {
            long index = CountIndex(chainId);

            try
            {
                byte[] indexBytes = RocksDBStoreBitConverter.GetBytes(index);

                byte[]             key = IndexKeyPrefix.Concat(indexBytes).ToArray();
                ColumnFamilyHandle cf  = GetColumnFamily(_chainDb, chainId);

                using var writeBatch = new WriteBatch();

                writeBatch.Put(key, hash.ToByteArray(), cf);
                writeBatch.Put(IndexCountKey, RocksDBStoreBitConverter.GetBytes(index + 1), cf);

                _chainDb.Write(writeBatch);
            }
            catch (Exception e)
            {
                LogUnexpectedException(nameof(AppendIndex), e);
            }

            return(index);
        }
コード例 #3
0
ファイル: RocksDBStore.cs プロジェクト: GunnerJnr/libplanet
        /// <inheritdoc/>
        public override void PutTransaction <T>(Transaction <T> tx)
        {
            if (_txCache.ContainsKey(tx.Id))
            {
                return;
            }

            byte[] key = TxKey(tx.Id);
            if (!(_txIndexDb.Get(key) is null))
            {
                return;
            }

            long   timestamp = tx.Timestamp.ToUnixTimeSeconds();
            string txDbName  = $"epoch{(int)timestamp / _txEpochUnitSeconds}";

            _rwTxLock.EnterWriteLock();
            try
            {
                if (!_txDbCache.TryGetValue(txDbName, out RocksDb txDb))
                {
                    txDb = RocksDBUtils.OpenRocksDb(_options, TxDbPath(txDbName));
                    _txDbCache.AddOrUpdate(txDbName, txDb);
                }

                txDb.Put(key, tx.Serialize(true));
                _txIndexDb.Put(key, RocksDBStoreBitConverter.GetBytes(txDbName));
                _txCache.AddOrUpdate(tx.Id, tx);
            }
            finally
            {
                _rwTxLock.ExitWriteLock();
            }
        }
コード例 #4
0
ファイル: RocksDBStore.cs プロジェクト: x86chi/libplanet
        private byte[] StateRefKey(string stateKey, long blockIndex)
        {
            byte[] stateKeyBytes   = RocksDBStoreBitConverter.GetBytes(stateKey);
            byte[] blockIndexBytes = RocksDBStoreBitConverter.GetBytes(blockIndex);

            return(StateRefKeyPrefix
                   .Concat(stateKeyBytes)
                   .Concat(blockIndexBytes)
                   .ToArray());
        }
コード例 #5
0
ファイル: RocksDBStore.cs プロジェクト: x86chi/libplanet
        /// <inheritdoc/>
        public override void IncreaseTxNonce(Guid chainId, Address signer, long delta = 1)
        {
            ColumnFamilyHandle cf = GetColumnFamily(_chainDb, chainId);
            long nextNonce        = GetTxNonce(chainId, signer) + delta;

            byte[] key   = TxNonceKey(signer);
            byte[] bytes = RocksDBStoreBitConverter.GetBytes(nextNonce);

            _chainDb.Put(key, bytes, cf);
        }
コード例 #6
0
        /// <inheritdoc/>
        public override void ForkBlockIndexes(
            Guid sourceChainId,
            Guid destinationChainId,
            HashDigest <SHA256> branchPoint)
        {
            HashDigest <SHA256>?genesisHash = IterateIndexes(sourceChainId, 0, 1)
                                              .Cast <HashDigest <SHA256>?>()
                                              .FirstOrDefault();

            if (genesisHash is null || branchPoint.Equals(genesisHash))
            {
                return;
            }

            ColumnFamilyHandle cf = GetColumnFamily(_chainDb, destinationChainId);
            var  writeBatch       = new WriteBatch();
            long index            = 0;

            try
            {
                foreach (Iterator it in IterateDb(_chainDb, IndexKeyPrefix, sourceChainId))
                {
                    byte[] hashBytes = it.Value();
                    writeBatch.Put(it.Key(), hashBytes, cf);
                    index += 1;

                    if (writeBatch.Count() >= ForkWriteBatchSize)
                    {
                        _chainDb.Write(writeBatch);
                        writeBatch.Dispose();
                        writeBatch = new WriteBatch();
                    }

                    if (branchPoint.ToByteArray().SequenceEqual(hashBytes))
                    {
                        break;
                    }
                }
            }
            finally
            {
                _chainDb.Write(writeBatch);
                writeBatch.Dispose();
            }

            _chainDb.Put(
                IndexCountKey,
                RocksDBStoreBitConverter.GetBytes(index),
                cf
                );
        }
コード例 #7
0
        /// <inheritdoc/>
        public override void PutBlock <T>(Block <T> block)
        {
            if (_blockCache.ContainsKey(block.Hash))
            {
                return;
            }

            byte[] key = BlockKey(block.Hash);

            if (!(_blockIndexDb.Get(key) is null))
            {
                return;
            }

            long timestamp = block.Timestamp.ToUnixTimeSeconds();

            foreach (Transaction <T> tx in block.Transactions)
            {
                PutTransaction(tx);
            }

            _rwBlockLock.EnterWriteLock();
            try
            {
                string  blockDbName = $"epoch{timestamp / _blockEpochUnitSeconds}";
                RocksDb blockDb;
                lock (_blockDbCache)
                {
                    if (!_blockDbCache.TryGetValue(blockDbName, out blockDb))
                    {
                        blockDb = RocksDBUtils.OpenRocksDb(_options, BlockDbPath(blockDbName));
                        _blockDbCache.AddOrUpdate(blockDbName, blockDb);
                    }
                }

                BlockDigest digest = BlockDigest.FromBlock(block);
                byte[]      value  = digest.Serialize();
                blockDb.Put(key, value);
                _blockIndexDb.Put(key, RocksDBStoreBitConverter.GetBytes(blockDbName));
                _blockCache.AddOrUpdate(block.Hash, digest);
            }
            catch (Exception e)
            {
                LogUnexpectedException(nameof(PutBlock), e);
            }
            finally
            {
                _rwBlockLock.ExitWriteLock();
            }
        }
コード例 #8
0
        /// <inheritdoc/>
        public override void IncreaseTxNonce(Guid chainId, Address signer, long delta = 1)
        {
            try
            {
                ColumnFamilyHandle cf = GetColumnFamily(_chainDb, chainId);
                long nextNonce        = GetTxNonce(chainId, signer) + delta;

                byte[] key   = TxNonceKey(signer);
                byte[] bytes = RocksDBStoreBitConverter.GetBytes(nextNonce);

                _chainDb.Put(key, bytes, cf);
            }
            catch (Exception e)
            {
                LogUnexpectedException(nameof(IncreaseTxNonce), e);
            }
        }
コード例 #9
0
ファイル: RocksDBStore.cs プロジェクト: x86chi/libplanet
        /// <inheritdoc/>
        public override long AppendIndex(Guid chainId, HashDigest <SHA256> hash)
        {
            long index = CountIndex(chainId);

            byte[] indexBytes = RocksDBStoreBitConverter.GetBytes(index);

            byte[]             key = IndexKeyPrefix.Concat(indexBytes).ToArray();
            ColumnFamilyHandle cf  = GetColumnFamily(_chainDb, chainId);

            using var writeBatch = new WriteBatch();

            writeBatch.Put(key, hash.ToByteArray(), cf);
            writeBatch.Put(IndexCountKey, RocksDBStoreBitConverter.GetBytes(index + 1), cf);

            _chainDb.Write(writeBatch);

            return(index);
        }
コード例 #10
0
        /// <inheritdoc cref="BaseStore.ForkBlockIndexes(Guid, Guid, BlockHash)"/>
        public override void ForkBlockIndexes(
            Guid sourceChainId,
            Guid destinationChainId,
            BlockHash branchpoint
            )
        {
            BlockHash?genesisHash = IterateIndexes(sourceChainId, 0, 1).FirstOrDefault();

            if (genesisHash is null || branchpoint.Equals(genesisHash))
            {
                return;
            }

            ColumnFamilyHandle srcCf  = GetColumnFamily(_chainDb, sourceChainId);
            ColumnFamilyHandle destCf = GetColumnFamily(_chainDb, destinationChainId);

            foreach (Iterator k in IterateDb(_chainDb, IndexKeyPrefix, destinationChainId))
            {
                _chainDb.Remove(k.Key(), destCf);
            }

            long bpIndex = GetBlockIndex(branchpoint).Value;

            if (GetPreviousChainInfo(srcCf) is { } chainInfo&&
                chainInfo.Item2 == bpIndex)
            {
                ForkBlockIndexes(chainInfo.Item1, destinationChainId, branchpoint);
                return;
            }

            _chainDb.Put(PreviousChainIdKey, sourceChainId.ToByteArray(), destCf);
            _chainDb.Put(
                PreviousChainIndexKey,
                RocksDBStoreBitConverter.GetBytes(bpIndex),
                destCf
                );
            _chainDb.Put(
                IndexCountKey,
                RocksDBStoreBitConverter.GetBytes(bpIndex + 1),
                destCf
                );
            AddFork(srcCf, destinationChainId);
        }
コード例 #11
0
        /// <inheritdoc cref="BaseStore.IndexBlockHash(Guid, long)"/>
        public override BlockHash?IndexBlockHash(Guid chainId, long index)
        {
            if (index < 0)
            {
                index += CountIndex(chainId);

                if (index < 0)
                {
                    return(null);
                }
            }

            ColumnFamilyHandle cf = GetColumnFamily(_chainDb, chainId);

            byte[] indexBytes = RocksDBStoreBitConverter.GetBytes(index);

            byte[] key   = IndexKeyPrefix.Concat(indexBytes).ToArray();
            byte[] bytes = _chainDb.Get(key, cf);
            return(bytes is null ? (BlockHash?)null : new BlockHash(bytes));
        }
コード例 #12
0
        private BlockHash?IndexBlockHash(Guid chainId, long index, bool includeDeleted)
        {
            try
            {
                if (index < 0)
                {
                    index += CountIndex(chainId);

                    if (index < 0)
                    {
                        return(null);
                    }
                }

                ColumnFamilyHandle cf = GetColumnFamily(_chainDb, chainId);

                if (!includeDeleted && IsDeletionMarked(cf))
                {
                    return(null);
                }

                if (GetPreviousChainInfo(cf) is { } chainInfo&&
                    chainInfo.Item2 >= index)
                {
                    return(IndexBlockHash(chainInfo.Item1, index, true));
                }

                byte[] indexBytes = RocksDBStoreBitConverter.GetBytes(index);

                byte[] key   = IndexKeyPrefix.Concat(indexBytes).ToArray();
                byte[] bytes = _chainDb.Get(key, cf);
                return(bytes is null ? (BlockHash?)null : new BlockHash(bytes));
            }
            catch (Exception e)
            {
                LogUnexpectedException(nameof(IndexBlockHash), e);
            }

            return(null);
        }