예제 #1
0
 public RewindData GetRewindData(int height)
 {
     using (DBreeze.Transactions.Transaction transaction = this.CreateTransaction())
     {
         transaction.SynchronizeTables("BlockHash", "Coins", "Rewind");
         Row <int, byte[]> row = transaction.Select <int, byte[]>("Rewind", height);
         return(row.Exists ? this.dBreezeSerializer.Deserialize <RewindData>(row.Value) : null);
     }
 }
예제 #2
0
        private T Get <T>(string rowKey, DBreeze.Transactions.Transaction tx)
        {
            var row = tx.Select <string, byte[]>(GetTableName <T>(), rowKey);

            if (row == null || !row.Exists)
            {
                return(default(T));
            }
            return(Serializer.ToObject <T>(Unzip(row.Value)));
        }
예제 #3
0
        public void InitializesGenBlockAndTxIndexOnFirstLoad()
        {
            string dir = CreateTestDir(this);

            using (IBlockRepository repository = this.SetupRepository(this.Network, dir))
            {
            }

            using (var engine = new DBreezeEngine(dir))
            {
                DBreeze.Transactions.Transaction transaction = engine.GetTransaction();

                Row <byte[], HashHeightPair> blockRow   = transaction.Select <byte[], HashHeightPair>("Common", new byte[0]);
                Row <byte[], bool>           txIndexRow = transaction.Select <byte[], bool>("Common", new byte[1]);

                Assert.Equal(this.Network.GetGenesis().GetHash(), blockRow.Value.Hash);
                Assert.False(txIndexRow.Value);
            }
        }
        protected virtual void OnInsertBlocks(DBreeze.Transactions.Transaction dbreezeTransaction, List <Block> blocks)
        {
            this.logger.LogTrace("({0}.{1}:{2})", nameof(blocks), nameof(blocks.Count), blocks?.Count);

            var transactions     = new List <(Transaction, Block)>();
            var byteListComparer = new ByteListComparer();
            var blockDict        = new Dictionary <uint256, Block>();

            // Gather blocks.
            foreach (Block block in blocks)
            {
                uint256 blockId = block.GetHash();
                blockDict[blockId] = block;
            }

            // Sort blocks. Be consistent in always converting our keys to byte arrays using the ToBytes method.
            List <KeyValuePair <uint256, Block> > blockList = blockDict.ToList();

            blockList.Sort((pair1, pair2) => byteListComparer.Compare(pair1.Key.ToBytes(), pair2.Key.ToBytes()));

            // Index blocks.
            foreach (KeyValuePair <uint256, Block> kv in blockList)
            {
                uint256 blockId = kv.Key;
                Block   block   = kv.Value;

                // If the block is already in store don't write it again.
                Row <byte[], Block> blockRow = dbreezeTransaction.Select <byte[], Block>("Block", blockId.ToBytes());
                if (!blockRow.Exists)
                {
                    this.PerformanceCounter.AddRepositoryMissCount(1);
                    this.PerformanceCounter.AddRepositoryInsertCount(1);
                    dbreezeTransaction.Insert <byte[], Block>("Block", blockId.ToBytes(), block);

                    if (this.TxIndex)
                    {
                        foreach (Transaction transaction in block.Transactions)
                        {
                            transactions.Add((transaction, block));
                        }
                    }
                }
                else
                {
                    this.PerformanceCounter.AddRepositoryHitCount(1);
                }
            }

            if (this.TxIndex)
            {
                this.OnInsertTransactions(dbreezeTransaction, transactions);
            }

            this.logger.LogTrace("(-)");
        }
        private Receipt GetReceipt(DBreeze.Transactions.Transaction t, uint256 hash)
        {
            byte[] result = t.Select <byte[], byte[]>(TableName, hash.ToBytes()).Value;

            if (result == null)
            {
                return(null);
            }

            return(Receipt.FromStorageBytesRlp(result));
        }
예제 #6
0
        /// <inheritdoc/>
        public Transaction[] GetTransactionsByIds(uint256[] trxids)
        {
            if (!this.TxIndex)
            {
                this.logger.LogTrace("(-)[TX_INDEXING_DISABLED]:null");
                return(null);
            }

            Transaction[] txes = new Transaction[trxids.Length];

            using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
            {
                transaction.ValuesLazyLoadingIsOn = false;

                for (int i = 0; i < trxids.Length; i++)
                {
                    Row <byte[], byte[]> transactionRow = transaction.Select <byte[], byte[]>(TransactionTableName, trxids[i].ToBytes());
                    if (!transactionRow.Exists)
                    {
                        this.logger.LogTrace("(-)[NO_TX_ROW]:null");
                        return(null);
                    }

                    Row <byte[], byte[]> blockRow = transaction.Select <byte[], byte[]>(BlockTableName, transactionRow.Value);

                    if (!blockRow.Exists)
                    {
                        this.logger.LogTrace("(-)[NO_BLOCK]:null");
                        return(null);
                    }

                    var         block = this.dBreezeSerializer.Deserialize <Block>(blockRow.Value);
                    Transaction tx    = block.Transactions.FirstOrDefault(t => t.GetHash() == trxids[i]);

                    txes[i] = tx;
                }
            }

            return(txes);
        }
        /// <inheritdoc />
        public Transaction GetTransactionById(uint256 trxid)
        {
            Guard.NotNull(trxid, nameof(trxid));

            if (!this.TxIndex)
            {
                this.logger.LogTrace("(-)[TX_INDEXING_DISABLED]:null");
                return(default(Transaction));
            }

            if (this.genesisTransactions.TryGetValue(trxid, out Transaction genesisTransaction))
            {
                return(genesisTransaction);
            }

            Transaction res = null;

            using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
            {
                transaction.ValuesLazyLoadingIsOn = false;

                Row <byte[], byte[]> transactionRow = transaction.Select <byte[], byte[]>(TransactionTableName, trxid.ToBytes());
                if (!transactionRow.Exists)
                {
                    this.logger.LogTrace("(-)[NO_BLOCK]:null");
                    return(null);
                }

                Row <byte[], byte[]> blockRow = transaction.Select <byte[], byte[]>(BlockTableName, transactionRow.Value);

                if (blockRow.Exists)
                {
                    var block = this.dBreezeSerializer.Deserialize <Block>(blockRow.Value);
                    res = block.Transactions.FirstOrDefault(t => t.GetHash() == trxid);
                }
            }

            return(res);
        }
예제 #8
0
        /// <summary>
        ///     Obtains a block header hash of the coinview's current tip.
        /// </summary>
        /// <param name="transaction">Open dBreeze transaction.</param>
        /// <returns>Block header hash of the coinview's current tip.</returns>
        uint256 GetTipHash(Transaction transaction)
        {
            if (this.blockHash == null)
            {
                var row = transaction.Select <byte[], byte[]>("BlockHash", blockHashKey);
                if (row.Exists)
                {
                    this.blockHash = new uint256(row.Value);
                }
            }

            return(this.blockHash);
        }
        /// <summary>
        /// Retrieves the current <see cref="HashHeightPair"/> tip from disk.
        /// </summary>
        /// <param name="transaction"> Open DBreeze transaction.</param>
        /// <returns> Hash of blocks current tip.</returns>
        private HashHeightPair GetTipHash(DBreeze.Transactions.Transaction transaction)
        {
            HashHeightPair tipHash = null;

            Row <byte[], byte[]> row = transaction.Select <byte[], byte[]>(BlockHashHeightTable, blockHashHeightKey);

            if (row.Exists)
            {
                tipHash = this.dBreezeSerializer.Deserialize <HashHeightPair>(row.Value);
            }

            return(tipHash);
        }
예제 #10
0
        /// <summary>
        /// Obtains a block header hash of the coinview's current tip.
        /// </summary>
        /// <param name="transaction">Open DBreeze transaction.</param>
        /// <returns>Block header hash of the coinview's current tip.</returns>
        private uint256 GetCurrentHash(DBreeze.Transactions.Transaction transaction)
        {
            if (this.blockHash == null)
            {
                Row <byte[], uint256> row = transaction.Select <byte[], uint256>("BlockHash", blockHashKey);
                if (row.Exists)
                {
                    this.blockHash = row.Value;
                }
            }

            return(this.blockHash);
        }
        /// <summary>
        /// Retrieves the current <see cref="HashHeightPair"/> tip from disk.
        /// </summary>
        /// <param name="transaction"> Open DBreeze transaction.</param>
        /// <returns> Hash of blocks current tip.</returns>
        private HashHeightPair GetTipHash(DBreeze.Transactions.Transaction transaction)
        {
            HashHeightPair tipHash = null;

            Row <byte[], HashHeightPair> row = transaction.Select <byte[], HashHeightPair>(BlockHashHeightTable, blockHashHeightKey);

            if (row.Exists)
            {
                tipHash = row.Value;
            }

            return(tipHash);
        }
        /// <inheritdoc />
        public Task <Transaction> GetTransactionByIdAsync(uint256 trxid)
        {
            this.logger.LogTrace("({0}:'{1}')", nameof(trxid), trxid);
            Guard.NotNull(trxid, nameof(trxid));

            if (!this.TxIndex)
            {
                return(Task.FromResult(default(Transaction)));
            }

            Task <Transaction> task = Task.Run(() =>
            {
                this.logger.LogTrace("()");
                Transaction res = null;
                using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
                {
                    transaction.ValuesLazyLoadingIsOn = false;

                    Row <byte[], uint256> transactionRow = transaction.Select <byte[], uint256>(TransactionTableName, trxid.ToBytes());
                    if (!transactionRow.Exists)
                    {
                        this.logger.LogTrace("(-)[NO_BLOCK]:null");
                        return(null);
                    }

                    Row <byte[], Block> blockRow = transaction.Select <byte[], Block>(BlockTableName, transactionRow.Value.ToBytes());
                    if (blockRow.Exists)
                    {
                        res = blockRow.Value.Transactions.FirstOrDefault(t => t.GetHash() == trxid);
                    }
                }

                this.logger.LogTrace("(-):{0}", res);
                return(res);
            });

            this.logger.LogTrace("(-)");
            return(task);
        }
        /// <summary>
        /// Obtains a block header hash of the coinview's current tip.
        /// </summary>
        /// <param name="transaction">Open dBreeze transaction.</param>
        /// <returns>Block header hash of the coinview's current tip.</returns>
        private uint256 GetTipHash(DBreeze.Transactions.Transaction transaction)
        {
            if (this.blockHash == null)
            {
                Row <byte[], byte[]> row = transaction.Select <byte[], byte[]>("BlockHash", blockHashKey);
                if (row.Exists)
                {
                    this.blockHash = new uint256(row.Value);
                }
            }

            return(this.blockHash);
        }
예제 #14
0
        public Task <RewindData> GetRewindData(int height)
        {
            Task <RewindData> task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.CreateTransaction())
                {
                    transaction.SynchronizeTables("BlockHash", "Coins", "Rewind");
                    Row <int, RewindData> row = transaction.Select <int, RewindData>("Rewind", height);
                    return(row.Exists ? row.Value : null);
                }
            });

            return(task);
        }
        private void DropIndex(string name, DBreeze.Transactions.Transaction transaction)
        {
            var indexTableName = IndexTableName(name);

            if (transaction.Select <string, string>("Common", indexTableName).Exists)
            {
                transaction.RemoveAllKeys(indexTableName, true);
                transaction.RemoveKey <string>("Common", indexTableName);
                if (this.tableNames.Contains(indexTableName))
                {
                    this.tableNames.Remove(indexTableName);
                }
            }
        }
예제 #16
0
        /// <summary>
        /// Obtains a block header hash of the coinview's current tip.
        /// </summary>
        /// <param name="transaction">Open dBreeze transaction.</param>
        /// <returns>Block header hash of the coinview's current tip.</returns>
        private HashHeightPair GetTipHash(DBreeze.Transactions.Transaction transaction)
        {
            if (this.blockHash == null)
            {
                Row <byte[], byte[]> row = transaction.Select <byte[], byte[]>("BlockHash", blockHashKey);
                if (row.Exists)
                {
                    this.blockHash = new HashHeightPair();
                    this.blockHash.FromBytes(row.Value);
                }
            }

            return(this.blockHash);
        }
예제 #17
0
        /// <inheritdoc />
        public SmartContractReceipt GetReceipt(uint256 txHash)
        {
            using (DBreeze.Transactions.Transaction t = this.engine.GetTransaction())
            {
                byte[] result = t.Select <byte[], byte[]>(TableName, txHash.ToBytes()).Value;

                if (result == null)
                {
                    return(null);
                }

                return(SmartContractReceipt.FromBytes(result));
            }
        }
        /// <inheritdoc />
        public Receipt Retrieve(uint256 hash)
        {
            using (DBreeze.Transactions.Transaction t = this.engine.GetTransaction())
            {
                byte[] result = t.Select <byte[], byte[]>(TableName, hash.ToBytes()).Value;

                if (result == null)
                {
                    return(null);
                }

                return(Receipt.FromStorageBytesRlp(result));
            }
        }
예제 #19
0
        public byte[] Get(byte[] key)
        {
            using (DBreeze.Transactions.Transaction t = this.engine.GetTransaction())
            {
                Row <byte[], byte[]> row = t.Select <byte[], byte[]>(this.table, key);

                if (row.Exists)
                {
                    return(row.Value);
                }

                return(null);
            }
        }
예제 #20
0
        public IndexRepository(Network network, string folder, IDateTimeProvider dateTimeProvider, ILoggerFactory loggerFactory, Dictionary <string, IndexExpression> requiredIndexes = null) :
            base(network, folder, dateTimeProvider, loggerFactory)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotEmpty(folder, nameof(folder));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));

            this.tableNames = new HashSet <string> {
                "Block", "Transaction", "Common"
            };
            this.Indexes         = new ConcurrentDictionary <string, Index>();
            this.requiredIndexes = requiredIndexes;

            using (DBreeze.Transactions.Transaction transaction = this.DBreeze.GetTransaction())
            {
                transaction.SynchronizeTables("Block", "Common");
                transaction.ValuesLazyLoadingIsOn = false;

                // Discover and add indexes to dictionary and tables to synchronize.
                foreach (Row <string, string> row in transaction.SelectForwardStartsWith <string, string>("Common", IndexTablePrefix))
                {
                    if (!row.Exists)
                    {
                        continue;
                    }

                    string name  = row.Key.Substring(IndexTablePrefix.Length);
                    Index  index = Index.Parse(this, row.Value, row.Key);
                    if (index.compiled != null)
                    {
                        this.Indexes.AddOrReplace(name, index);
                        if (!this.tableNames.Contains(row.Key))
                        {
                            this.tableNames.Add(row.Key);
                        }
                    }
                }

                // Remove any index tables that are not being used (not transactional).
                foreach (string indexTable in this.GetIndexTables())
                {
                    if (!transaction.Select <string, string>("Common", indexTable).Exists)
                    {
                        this.DeleteIndexTable(indexTable);
                    }
                }
            }
        }
        private void LoadPrunedTip(DBreeze.Transactions.Transaction dbreezeTransaction)
        {
            if (this.PrunedTip == null)
            {
                dbreezeTransaction.ValuesLazyLoadingIsOn = false;

                Row <byte[], byte[]> row = dbreezeTransaction.Select <byte[], byte[]>(BlockRepository.CommonTableName, prunedTipKey);
                if (row.Exists)
                {
                    this.PrunedTip = this.dBreezeSerializer.Deserialize <HashHeightPair>(row.Value);
                }

                dbreezeTransaction.ValuesLazyLoadingIsOn = true;
            }
        }
        public Task LoadAsync(ConcurrentChain chain)
        {
            Guard.Assert(chain.Tip == chain.Genesis);

            Task task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
                {
                    transaction.ValuesLazyLoadingIsOn = false;
                    ChainedBlock tip = null;
                    Row <int, BlockHeader> firstRow = transaction.Select <int, BlockHeader>("Chain", 0);

                    if (!firstRow.Exists)
                    {
                        return;
                    }

                    BlockHeader previousHeader = firstRow.Value;
                    Guard.Assert(previousHeader.GetHash() == chain.Genesis.HashBlock); // can't swap networks

                    foreach (Row <int, BlockHeader> row in transaction.SelectForwardSkip <int, BlockHeader>("Chain", 1))
                    {
                        if ((tip != null) && (previousHeader.HashPrevBlock != tip.HashBlock))
                        {
                            break;
                        }

                        tip            = new ChainedBlock(previousHeader, row.Value.HashPrevBlock, tip);
                        previousHeader = row.Value;
                    }

                    if (previousHeader != null)
                    {
                        tip = new ChainedBlock(previousHeader, null, tip);
                    }

                    if (tip == null)
                    {
                        return;
                    }

                    this.locator = tip.GetLocator();
                    chain.SetTip(tip);
                }
            });

            return(task);
        }
예제 #23
0
        /// <inheritdoc />
        public Task <ChainedHeader> LoadAsync(ChainedHeader genesisHeader)
        {
            Task <ChainedHeader> task = Task.Run(() =>
            {
                using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
                {
                    transaction.ValuesLazyLoadingIsOn = false;
                    ChainedHeader tip          = null;
                    Row <int, byte[]> firstRow = transaction.Select <int, byte[]>("Chain", 0);

                    if (!firstRow.Exists)
                    {
                        return(genesisHeader);
                    }

                    BlockHeader previousHeader = this.dBreezeSerializer.Deserialize <BlockHeader>(firstRow.Value);
                    Guard.Assert(previousHeader.GetHash() == genesisHeader.HashBlock); // can't swap networks

                    foreach (Row <int, byte[]> row in transaction.SelectForwardSkip <int, byte[]>("Chain", 1))
                    {
                        if ((tip != null) && (previousHeader.HashPrevBlock != tip.HashBlock))
                        {
                            break;
                        }

                        BlockHeader blockHeader = this.dBreezeSerializer.Deserialize <BlockHeader>(row.Value);
                        tip            = new ChainedHeader(previousHeader, blockHeader.HashPrevBlock, tip);
                        previousHeader = blockHeader;
                    }

                    if (previousHeader != null)
                    {
                        tip = new ChainedHeader(previousHeader, previousHeader.GetHash(), tip);
                    }

                    if (tip == null)
                    {
                        tip = genesisHeader;
                    }

                    this.locator = tip.GetLocator();
                    return(tip);
                }
            });

            return(task);
        }
예제 #24
0
        private HashHeightPair LoadTip()
        {
            using (DBreeze.Transactions.Transaction transaction = this.dBreeze.GetTransaction())
            {
                Row <byte[], byte[]> tipRow = transaction.Select <byte[], byte[]>(TableName, TipKey.ToBytes());

                if (!tipRow.Exists)
                {
                    this.logger.LogTrace("(-)[NO_TIP]:null");
                    return(null);
                }

                var loadedTip = this.dBreezeSerializer.Deserialize <HashHeightPair>(tipRow.Value);

                return(loadedTip);
            }
        }
예제 #25
0
        public void Initialize()
        {
            // Load highest index.
            this.highestPollId = -1;

            using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
            {
                Row <byte[], int> row = transaction.Select <byte[], int>(TableName, RepositoryHighestIndexKey);

                if (row.Exists)
                {
                    this.highestPollId = row.Value;
                }
            }

            this.logger.LogDebug("Polls repo initialized with highest id: {0}.", this.highestPollId);
        }
예제 #26
0
        /// <summary>
        /// Not used util
        /// </summary>
        /// <param name="tran"></param>
        /// <param name="table"></param>
        /// <param name="counterAddress"></param>
        /// <returns></returns>
        long GetTableCounterLong(DBreeze.Transactions.Transaction tran, string table, byte[] counterAddress)
        {
            long counter = 1;
            var  row     = tran.Select <byte[], long>(table, counterAddress);

            if (!row.Exists)
            {
                tran.Insert <byte[], long>(table, counterAddress, 1);
                return(counter);
            }

            counter = row.Value;

            counter++;
            tran.Insert(table, counterAddress, counter);
            return(counter);
        }
예제 #27
0
        private void CreateIndex(DBreeze.Transactions.Transaction dbreezeTransaction, string name, bool multiValue, string builder, string[] dependencies)
        {
            if (this.Indexes.ContainsKey(name))
            {
                throw new IndexStoreException("The '" + name + "' index already exists");
            }

            var index = new Index(this, name, multiValue, builder, dependencies);

            this.Indexes[name] = index;

            Row <string, string> dbIndexRow = dbreezeTransaction.Select <string, string>("Common", index.Table);

            if (dbIndexRow.Exists)
            {
                dbreezeTransaction.RemoveAllKeys(index.Table, true);
            }

            if (!this.tableNames.Contains(index.Table))
            {
                this.tableNames.Add(index.Table);
            }

            var transactions = new List <(Transaction, Block)>();

            foreach (Row <byte[], Block> row in dbreezeTransaction.SelectForward <byte[], Block>("Block"))
            {
                Block  block = row.Value;
                byte[] key   = block.GetHash().ToBytes();

                foreach (Transaction transaction in block.Transactions)
                {
                    transactions.Add((transaction, block));
                }

                if (transactions.Count >= 5000)
                {
                    index.IndexTransactionDetails(dbreezeTransaction, transactions);
                    transactions.Clear();
                }
            }

            index.IndexTransactionDetails(dbreezeTransaction, transactions);
            dbreezeTransaction.Insert <string, string>("Common", index.Table, index.ToString());
        }
        protected virtual void OnInsertBlocks(DBreeze.Transactions.Transaction dbreezeTransaction, List <Block> blocks)
        {
            var transactions     = new List <(Transaction, Block)>();
            var byteListComparer = new ByteListComparer();
            var blockDict        = new Dictionary <uint256, Block>();

            // Gather blocks.
            foreach (Block block in blocks)
            {
                uint256 blockId = block.GetHash();
                blockDict[blockId] = block;
            }

            // Sort blocks. Be consistent in always converting our keys to byte arrays using the ToBytes method.
            List <KeyValuePair <uint256, Block> > blockList = blockDict.ToList();

            blockList.Sort((pair1, pair2) => byteListComparer.Compare(pair1.Key.ToBytes(), pair2.Key.ToBytes()));

            // Index blocks.
            foreach (KeyValuePair <uint256, Block> kv in blockList)
            {
                uint256 blockId = kv.Key;
                Block   block   = kv.Value;

                // If the block is already in store don't write it again.
                Row <byte[], byte[]> blockRow = dbreezeTransaction.Select <byte[], byte[]>(BlockTableName, blockId.ToBytes());
                if (!blockRow.Exists)
                {
                    dbreezeTransaction.Insert <byte[], byte[]>(BlockTableName, blockId.ToBytes(), this.dBreezeSerializer.Serialize(block));

                    if (this.TxIndex)
                    {
                        foreach (Transaction transaction in block.Transactions)
                        {
                            transactions.Add((transaction, block));
                        }
                    }
                }
            }

            if (this.TxIndex)
            {
                this.OnInsertTransactions(dbreezeTransaction, transactions);
            }
        }
예제 #29
0
        /// <summary>Loads all polls from the database.</summary>
        public List <Poll> GetAllPolls()
        {
            using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
            {
                var polls = new List <Poll>(this.highestPollId + 1);

                for (int i = 0; i < this.highestPollId + 1; i++)
                {
                    Row <byte[], byte[]> row = transaction.Select <byte[], byte[]>(TableName, i.ToBytes());

                    Poll poll = this.dBreezeSerializer.Deserialize <Poll>(row.Value);

                    polls.Add(poll);
                }

                return(polls);
            }
        }
예제 #30
0
        /// <summary>Updates existing poll.</summary>
        public void UpdatePoll(Poll poll)
        {
            using (DBreeze.Transactions.Transaction transaction = this.dbreeze.GetTransaction())
            {
                Row <byte[], byte[]> row = transaction.Select <byte[], byte[]>(TableName, poll.Id.ToBytes());

                if (!row.Exists)
                {
                    throw new ArgumentException("Value doesn't exist!");
                }

                byte[] bytes = this.dBreezeSerializer.Serialize(poll);

                transaction.Insert <byte[], byte[]>(TableName, poll.Id.ToBytes(), bytes);

                transaction.Commit();
            }
        }