public async Task <string> SendTransaction(string transactionHex)
        {
            // todo: consider adding support for retries.
            // todo: check how a failure is porpageted

            SyncConnection connection = syncConnection;
            Transaction    trx        = null;

            // parse the trx;
            trx = connection.Network.Consensus.ConsensusFactory.CreateTransaction(transactionHex);
            trx.PrecomputeHash(false, true);

            IBlockchainClient client = clientFactory.Create(connection);
            string            trxid  = await client.SentRawTransactionAsync(transactionHex);

            if (trx.GetHash().ToString() != trxid)
            {
                throw new Exception($"node trxid = {trxid}, serialized trxid = {trx.GetHash().ToString()}");
            }

            storageOperations.InsertMempoolTransactions(new SyncBlockTransactionsOperation
            {
                Transactions = new List <Transaction> {
                    trx
                }
            });

            return(trxid);
        }
Exemplo n.º 2
0
        public async Task <SyncBlockInfo> RewindToBestChain(SyncConnection connection)
        {
            IBlockchainClient client = clientFactory.Create(connection);

            while (true)
            {
                SyncBlockInfo block = storage.GetLatestBlock();

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

                string currentHash = await client.GetblockHashAsync(block.BlockIndex);

                if (currentHash == block.BlockHash)
                {
                    return(block);
                }

                log.LogDebug($"Rewinding block {block.BlockIndex}({block.BlockHash})");

                await storage.DeleteBlockAsync(block.BlockHash);
            }
        }
        public async Task CompareAddressBalances()
        {
            IAddressInfoService addressInfoService = Instantiate <IAddressInfoService>();
            IBlockchainClient   blockchainClient   = Instantiate <IBlockchainClient>();

            IEnumerable <string> addresses = new List <string>();

            using (var uow = NewUnitOfWork())
            {
                addresses = NewRepository <Address>(uow).GetAs(a => true, a => a.BlockchainAddress);
            }

            foreach (var address in addresses)
            {
                var databaseResult = addressInfoService.GetAddressInfo(address);
                Assert.True(databaseResult.Successful, $"Retrieving address {address} from database failed.");

                var blockchainResult = await blockchainClient.GetAddressInfo(address);

                Assert.True(blockchainResult.Successful, $"Retrieving address {address} from blockchain failed.");

                var addressInfoDto       = databaseResult.Data;
                var addressBlockchainDto = blockchainResult.Data;

                Assert.True(addressBlockchainDto.Balance.Available == addressInfoDto.ChxBalanceInfo.AvailableBalance, $"Available CHX for {address} does not match.");
                Assert.True(addressBlockchainDto.Balance.Deposit == addressInfoDto.ChxBalanceInfo.ValidatorDeposit, $"Deposited CHX for {address} does not match.");
                Assert.True(addressBlockchainDto.Balance.Staked == addressInfoDto.ChxBalanceInfo.DelegatedStakes, $"Staked CHX for {address} does not match.");
            }
        }
Exemplo n.º 4
0
        private SyncBlockTransactionsOperation SyncPoolInternal(SyncConnection connection, SyncPoolTransactions poolTransactions)
        {
            IBlockchainClient client = clientFactory.Create(connection);

            SyncBlockTransactionsOperation returnBlock = SyncBlockTransactions(client, connection, poolTransactions.Transactions, false);

            return(returnBlock);
        }
Exemplo n.º 5
0
        public string GetRawBlock(string blockHash)
        {
            IBlockchainClient client = clientFactory.Create(syncConnection);

            string res = client.GetBlockHex(blockHash);

            return(res);
        }
Exemplo n.º 6
0
        public override async Task OnExecute()
        {
            IBlockchainClient client = clientFactory.Create(connection);

            List <string> allIndexes = mongoData.GetBlockIndexIndexes();

            if (allIndexes.Count == BlockIndexer.ExpectedNumberOfIndexes)
            {
                Runner.GlobalState.IndexModeCompleted = true;
            }

            Runner.GlobalState.PullingTip = null;
            Runner.GlobalState.StoreTip   = null;

            Runner.GlobalState.StoreTip = await syncOperations.RewindToLastCompletedBlockAsync();

            if (Runner.GlobalState.StoreTip == null)
            {
                // No blocks in store start from zero
                // push the genesis block to store
                int    start       = 0;
                string genesisHash = await client.GetblockHashAsync(start);


                log.LogInformation($"Processing genesis hash = {genesisHash}");

                BlockInfo genesisBlock = await client.GetBlockAsync(genesisHash);

                SyncBlockTransactionsOperation block = syncOperations.FetchFullBlock(connection, genesisBlock);

                StorageBatch genesisBatch = new StorageBatch();
                storageOperations.AddToStorageBatch(genesisBatch, block);
                Runner.GlobalState.StoreTip = storageOperations.PushStorageBatch(genesisBatch);
            }

            BlockInfo fetchedBlock = await client.GetBlockAsync(Runner.GlobalState.StoreTip.BlockHash);

            if (fetchedBlock == null)
            {
                // check if the fullnode is ahead of the indexer height
                int fullnodeTipHeight = client.GetBlockCount();
                if (fullnodeTipHeight < Runner.GlobalState.StoreTip.BlockIndex)
                {
                    throw new ApplicationException($"Full node at height {fullnodeTipHeight} which is behind the Indexer at height {Runner.GlobalState.StoreTip.BlockIndex}");
                }

                // reorg happend while indexer was offline rewind the indexer database
                Runner.GlobalState.PullingTip = null;
                Runner.GlobalState.StoreTip   = null;

                Runner.GlobalState.StoreTip = await syncOperations.RewindToBestChain(connection);
            }

            // update the chains tip
            Runner.GlobalState.ChainTipHeight = syncOperations.GetBlockCount(client);
        }
 public ImportService(
     IUnitOfWorkFactory unitOfWorkFactory,
     IRepositoryFactory repositoryFactory,
     IBlockchainClient blockchainClient,
     IActionService actionService)
     : base(unitOfWorkFactory, repositoryFactory)
 {
     _blockchainClient = blockchainClient;
     _actionService    = actionService;
 }
Exemplo n.º 8
0
 public ScannerService(
     IBlockchainClient blockchainClient,
     IImportService importService,
     IUnitOfWorkFactory unitOfWorkFactory,
     IRepositoryFactory repositoryFactory)
     : base(unitOfWorkFactory, repositoryFactory)
 {
     _blockchainClient = blockchainClient;
     _importService    = importService;
 }
Exemplo n.º 9
0
        public async Task <StatsConnection> StatsConnection()
        {
            SyncConnection    connection = syncConnection;
            IBlockchainClient client     = clientFactory.Create(connection);

            int clientConnection = await client.GetConnectionCountAsync();

            return(new StatsConnection {
                Connections = clientConnection
            });
        }
Exemplo n.º 10
0
        public long GetBlockCount(IBlockchainClient client)
        {
            if (!cache.TryGetValue(CacheKeys.BlockCount, out long cacheEntry))
            {
                cacheEntry = client.GetBlockCount();

                // Save data in cache.
                cache.Set(CacheKeys.BlockCount, cacheEntry, cacheOptions);
            }

            return(cacheEntry);
        }
Exemplo n.º 11
0
        public string GetRawTransaction(string transactionId)
        {
            // Try to find the trx in disk
            SyncRawTransaction rawtrx = TransactionGetByHash(transactionId);

            if (rawtrx != null)
            {
                return(Encoders.Hex.EncodeData(rawtrx.RawTransaction));
            }

            IBlockchainClient client = clientFactory.Create(syncConnection);

            Client.Types.DecodedRawTransaction res = client.GetRawTransactionAsync(transactionId, 0).Result;

            if (res.Hex != null)
            {
                return(res.Hex);
            }

            return(null);
        }
Exemplo n.º 12
0
        private SyncBlockTransactionsOperation SyncBlockTransactions(IBlockchainClient client, SyncConnection connection, IEnumerable <string> transactionsToSync, bool throwIfNotFound)
        {
            var itemList = transactionsToSync.Select(t => new tcalc {
                item = t
            }).ToList();

            var options = new ParallelOptions {
                MaxDegreeOfParallelism = configuration.ParallelRequestsToTransactionRpc
            };

            Parallel.ForEach(itemList, options, (item) =>
            {
                try
                {
                    item.result = client.GetRawTransaction(item.item, 0);
                }
                catch (BitcoinClientException bce)
                {
                    if (!throwIfNotFound && bce.IsTransactionNotFound())
                    {
                        //// the transaction was not found in the client,
                        //// if this is a pool sync we assume the transaction was initially found in the pool and became invalid.
                        return;
                    }

                    throw;
                }
            });

            IEnumerable <Transaction> transactions = itemList.Where(t => t.result != null).Select(s =>
            {
                Transaction trx = connection.Network.Consensus.ConsensusFactory.CreateTransaction(s.result.Hex);
                trx.PrecomputeHash(false, true);
                return(trx);
            });

            return(new SyncBlockTransactionsOperation {
                Transactions = transactions.ToList()
            });
        }
Exemplo n.º 13
0
        private SyncPoolTransactions FindPoolInternal(SyncConnection connection)
        {
            IBlockchainClient client = clientFactory.Create(connection);

            IEnumerable <string> memPool = client.GetRawMemPool();

            var currentMemoryPool = new HashSet <string>(memPool);
            var currentTable      = new HashSet <string>(globalState.LocalMempoolView.Keys);

            var newTransactions   = currentMemoryPool.Except(currentTable).ToList();
            var deleteTransaction = currentTable.Except(currentMemoryPool).ToList();

            // limit to 1k trx per loop
            newTransactions = newTransactions.Take(1000).ToList();

            // entries deleted from mempool on the node
            // we also delete it in our store
            if (deleteTransaction.Any())
            {
                List <string> toRemoveFromMempool = deleteTransaction;

                FilterDefinitionBuilder <MempoolTable> builder = Builders <MempoolTable> .Filter;
                FilterDefinition <MempoolTable>        filter  = builder.In(mempoolItem => mempoolItem.TransactionId, toRemoveFromMempool);

                db.Mempool.DeleteMany(filter);

                foreach (string mempooltrx in toRemoveFromMempool)
                {
                    globalState.LocalMempoolView.Remove(mempooltrx, out _);
                }
            }

            return(new SyncPoolTransactions {
                Transactions = newTransactions
            });
        }
        public async Task CompareAccountHoldings()
        {
            IBlockchainInfoService blockchainInfoService = Instantiate <IBlockchainInfoService>();
            IBlockchainClient      blockchainClient      = Instantiate <IBlockchainClient>();

            IEnumerable <string> accounts = new List <string>();

            using (var uow = NewUnitOfWork())
            {
                accounts = NewRepository <Account>(uow).GetAs(a => true, a => a.Hash);
            }

            foreach (var account in accounts)
            {
                var databaseResult = blockchainInfoService.GetAccountInfo(account);
                Assert.True(databaseResult.Successful, $"Retrieving account {account} from database failed.");

                var blockchainResult = await blockchainClient.GetAccountInfo(account);

                Assert.True(blockchainResult.Successful, $"Retrieving account {account} from blockchain failed.");

                var accountInfoDto       = databaseResult.Data;
                var accountBlockchainDto = blockchainResult.Data;

                Assert.Equal(accountBlockchainDto.Holdings.Count, accountInfoDto.Holdings.Count);

                foreach (var holdingInfo in accountInfoDto.Holdings)
                {
                    var holdingBlockchain = accountBlockchainDto.Holdings
                                            .FirstOrDefault(h => h.AssetHash == holdingInfo.AssetHash);

                    Assert.NotNull(holdingBlockchain);
                    Assert.Equal(holdingBlockchain.Balance, holdingInfo.Balance);
                }
            }
        }