/// <summary>
        /// Constructs the cold staking manager which is used by the cold staking controller.
        /// </summary>
        /// <param name="network">The network that the manager is running on.</param>
        /// <param name="chain">Thread safe class representing a chain of headers from genesis.</param>
        /// <param name="walletSettings">The wallet settings.</param>
        /// <param name="dataFolder">Contains path locations to folders and files on disk.</param>
        /// <param name="walletFeePolicy">The wallet fee policy.</param>
        /// <param name="asyncLoopFactory">Factory for creating and also possibly starting application defined tasks inside async loop.</param>
        /// <param name="nodeLifeTime">Allows consumers to perform cleanup during a graceful shutdown.</param>
        /// <param name="scriptAddressReader">A reader for extracting an address from a <see cref="Script"/>.</param>
        /// <param name="loggerFactory">The logger factory to use to create the custom logger.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="broadcasterManager">The broadcaster manager.</param>
        public ColdStakingManager(
            Network network,
            ConcurrentChain chain,
            WalletSettings walletSettings,
            DataFolder dataFolder,
            IWalletFeePolicy walletFeePolicy,
            IAsyncLoopFactory asyncLoopFactory,
            INodeLifetime nodeLifeTime,
            IScriptAddressReader scriptAddressReader,
            ILoggerFactory loggerFactory,
            IDateTimeProvider dateTimeProvider,
            IBroadcasterManager broadcasterManager = null) : base(
                loggerFactory,
                network,
                chain,
                walletSettings,
                dataFolder,
                walletFeePolicy,
                asyncLoopFactory,
                nodeLifeTime,
                dateTimeProvider,
                scriptAddressReader,
                broadcasterManager
                )
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));

            this.logger           = loggerFactory.CreateLogger(this.GetType().FullName);
            this.dateTimeProvider = dateTimeProvider;
        }
示例#2
0
 public TransactionsToListsBase(Network network, IScriptAddressReader scriptAddressReader, IWalletTransactionLookup transactionsOfInterest, IWalletAddressLookup addressesOfInterest)
 {
     this.network                = network;
     this.scriptAddressReader    = scriptAddressReader;
     this.transactionsOfInterest = transactionsOfInterest;
     this.addressesOfInterest    = addressesOfInterest;
 }
示例#3
0
        public BlockStoreController(
            Network network,
            ILoggerFactory loggerFactory,
            IBlockStore blockStore,
            IChainState chainState,
            ChainIndexer chainIndexer,
            IAddressIndexer addressIndexer,
            IUtxoIndexer utxoIndexer,
            IScriptAddressReader scriptAddressReader,
            IStakeChain stakeChain = null)
        {
            Guard.NotNull(network, nameof(network));
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(chainState, nameof(chainState));
            Guard.NotNull(addressIndexer, nameof(addressIndexer));
            Guard.NotNull(utxoIndexer, nameof(utxoIndexer));

            this.addressIndexer      = addressIndexer;
            this.network             = network;
            this.blockStore          = blockStore;
            this.chainState          = chainState;
            this.chainIndexer        = chainIndexer;
            this.utxoIndexer         = utxoIndexer;
            this.scriptAddressReader = scriptAddressReader;
            this.stakeChain          = stakeChain;
            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);
        }
示例#4
0
        public AddressIndexer(StoreSettings storeSettings, DataFolder dataFolder, ILoggerFactory loggerFactory, Network network, INodeStats nodeStats,
                              IConsensusManager consensusManager, IAsyncProvider asyncProvider, ChainIndexer chainIndexer, IDateTimeProvider dateTimeProvider, IUtxoIndexer utxoIndexer)
        {
            this.storeSettings       = storeSettings;
            this.network             = network;
            this.nodeStats           = nodeStats;
            this.dataFolder          = dataFolder;
            this.consensusManager    = consensusManager;
            this.asyncProvider       = asyncProvider;
            this.dateTimeProvider    = dateTimeProvider;
            this.utxoIndexer         = utxoIndexer;
            this.loggerFactory       = loggerFactory;
            this.scriptAddressReader = new ScriptAddressReader();

            this.lockObject           = new object();
            this.flushChangesInterval = TimeSpan.FromMinutes(2);
            this.lastFlushTime        = this.dateTimeProvider.GetUtcNow();
            this.cancellation         = new CancellationTokenSource();
            this.chainIndexer         = chainIndexer;
            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.averageTimePerBlock = new AverageCalculator(200);
            int maxReorgLength = GetMaxReorgOrFallbackMaxReorg(this.network);

            this.compactionTriggerDistance = maxReorgLength * 2 + SyncBuffer + 1000;
        }
示例#5
0
 public SmartContractScriptAddressReader(
     ScriptAddressReader addressReader,
     ICallDataSerializer callDataSerializer)
 {
     this.baseAddressReader  = addressReader;
     this.callDataSerializer = callDataSerializer;
 }
示例#6
0
        /// <summary>
        /// Constructs the cold staking manager which is used by the cold staking controller.
        /// </summary>
        /// <param name="network">The network that the manager is running on.</param>
        /// <param name="chainIndexer">Thread safe class representing a chain of headers from genesis.</param>
        /// <param name="walletSettings">The wallet settings.</param>
        /// <param name="dataFolder">Contains path locations to folders and files on disk.</param>
        /// <param name="walletFeePolicy">The wallet fee policy.</param>
        /// <param name="asyncProvider">Factory for creating and also possibly starting application defined tasks inside async loop.</param>
        /// <param name="nodeLifeTime">Allows consumers to perform cleanup during a graceful shutdown.</param>
        /// <param name="scriptAddressReader">A reader for extracting an address from a <see cref="Script"/>.</param>
        /// <param name="loggerFactory">The logger factory to use to create the custom logger.</param>
        /// <param name="dateTimeProvider">Provider of time functions.</param>
        /// <param name="broadcasterManager">The broadcaster manager.</param>
        public ColdStakingManager(
            Network network,
            ChainIndexer chainIndexer,
            WalletSettings walletSettings,
            DataFolder dataFolder,
            IWalletFeePolicy walletFeePolicy,
            IAsyncProvider asyncProvider,
            INodeLifetime nodeLifeTime,
            IScriptAddressReader scriptAddressReader,
            ILoggerFactory loggerFactory,
            IDateTimeProvider dateTimeProvider,
            IBroadcasterManager broadcasterManager = null) : base(
                loggerFactory,
                network,
                chainIndexer,
                walletSettings,
                dataFolder,
                walletFeePolicy,
                asyncProvider,
                nodeLifeTime,
                dateTimeProvider,
                scriptAddressReader,
                broadcasterManager
                )
        {
            Guard.NotNull(loggerFactory, nameof(loggerFactory));
            Guard.NotNull(dateTimeProvider, nameof(dateTimeProvider));

            this.logger           = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode");
            this.dateTimeProvider = dateTimeProvider;
        }
示例#7
0
 internal TransactionsToLists(Network network, IScriptAddressReader scriptAddressReader, ProcessBlocksInfo processBlocksInfo)
     : base(network, scriptAddressReader, processBlocksInfo.TransactionsOfInterest, processBlocksInfo.AddressesOfInterest)
 {
     this.conn = processBlocksInfo.Conn;
     this.processBlocksInfo = processBlocksInfo;
     this.trackers          = new Dictionary <TopUpTracker, TopUpTracker>();
 }
示例#8
0
 public WalletRPCController(
     IBlockStore blockStore,
     IBroadcasterManager broadcasterManager,
     ChainIndexer chainIndexer,
     IConsensusManager consensusManager,
     IFullNode fullNode,
     ILoggerFactory loggerFactory,
     Network network,
     IScriptAddressReader scriptAddressReader,
     StoreSettings storeSettings,
     IWalletManager walletManager,
     IWalletService walletService,
     WalletSettings walletSettings,
     IWalletTransactionHandler walletTransactionHandler,
     IWalletSyncManager walletSyncManager,
     IReserveUtxoService reserveUtxoService = null) : base(fullNode: fullNode, consensusManager: consensusManager, chainIndexer: chainIndexer, network: network)
 {
     this.blockStore               = blockStore;
     this.broadcasterManager       = broadcasterManager;
     this.logger                   = loggerFactory.CreateLogger(this.GetType().FullName);
     this.scriptAddressReader      = scriptAddressReader;
     this.storeSettings            = storeSettings;
     this.walletManager            = walletManager;
     this.walletService            = walletService;
     this.walletSettings           = walletSettings;
     this.walletTransactionHandler = walletTransactionHandler;
     this.walletSyncManager        = walletSyncManager;
     this.reserveUtxoService       = reserveUtxoService;
 }
 public WalletTransactionHandlerTest()
 {
     // adding this data to the transaction output should increase the fee
     // 83 is the max size for the OP_RETURN script => 80 is the max for the content of the script
     byte[] maxQuantityOfBytes = Enumerable.Range(0, 80).Select(Convert.ToByte).ToArray();
     this.costlyOpReturnData        = Encoding.UTF8.GetString(maxQuantityOfBytes);
     this.standardTransactionPolicy = new StandardTransactionPolicy(this.Network);
     this.scriptAddressReader       = new ScriptAddressReader();
 }
示例#10
0
 public ColdStakingWalletRPCController(
     IBlockStore blockStore,
     IBroadcasterManager broadcasterManager,
     ChainIndexer chainIndexer,
     IConsensusManager consensusManager,
     IFullNode fullNode,
     ILoggerFactory loggerFactory,
     Network network,
     IScriptAddressReader scriptAddressReader,
     StoreSettings storeSettings,
     IWalletManager walletManager,
     WalletSettings walletSettings,
     IWalletTransactionHandler walletTransactionHandler) :
     base(blockStore, broadcasterManager, chainIndexer, consensusManager, fullNode, loggerFactory, network, scriptAddressReader, storeSettings, walletManager, walletSettings, walletTransactionHandler)
 {
 }
示例#11
0
        public AddressIndexer(StoreSettings storeSettings, DataFolder dataFolder, ILoggerFactory loggerFactory, Network network, INodeStats nodeStats, IConsensusManager consensusManager, IAsyncProvider asyncProvider)
        {
            this.storeSettings       = storeSettings;
            this.network             = network;
            this.nodeStats           = nodeStats;
            this.dataFolder          = dataFolder;
            this.consensusManager    = consensusManager;
            this.asyncProvider       = asyncProvider;
            this.loggerFactory       = loggerFactory;
            this.scriptAddressReader = new ScriptAddressReader();

            this.lockObject           = new object();
            this.flushChangesInterval = TimeSpan.FromMinutes(10);
            this.lastFlushTime        = DateTime.Now;
            this.cancellation         = new CancellationTokenSource();
            this.logger = loggerFactory.CreateLogger(this.GetType().FullName);

            this.averageTimePerBlock = new AverageCalculator(200);
        }
 public WalletRPCController(
     IBlockStore blockStore,
     IBroadcasterManager broadcasterManager,
     ChainIndexer chainIndexer,
     IConsensusManager consensusManager,
     IFullNode fullNode,
     ILoggerFactory loggerFactory,
     Network network,
     IScriptAddressReader scriptAddressReader,
     StoreSettings storeSettings,
     IWalletManager walletManager,
     WalletSettings walletSettings,
     IWalletTransactionHandler walletTransactionHandler) : base(fullNode: fullNode, consensusManager: consensusManager, chainIndexer: chainIndexer, network: network)
 {
     this.blockStore               = blockStore;
     this.broadcasterManager       = broadcasterManager;
     this.logger                   = loggerFactory.CreateLogger("Impleum.Bitcoin.Fullnode");
     this.scriptAddressReader      = scriptAddressReader;
     this.storeSettings            = storeSettings;
     this.walletManager            = walletManager;
     this.walletSettings           = walletSettings;
     this.walletTransactionHandler = walletTransactionHandler;
 }
 internal TransactionsToLists(Network network, IScriptAddressReader scriptAddressReader, ProcessBlocksInfo processBlocksInfo, IDateTimeProvider dateTimeProvider)
     : base(network, scriptAddressReader, processBlocksInfo.TransactionsOfInterest, processBlocksInfo.AddressesOfInterest, dateTimeProvider)
 {
     this.conn = processBlocksInfo.Conn;
     this.processBlocksInfo = processBlocksInfo;
 }
 public ScriptDestinationReader(IScriptAddressReader scriptAddressReader)
 {
     this.scriptAddressReader = scriptAddressReader;
 }
        public GetTransactionModel GetTransaction(string txid)
        {
            if (!uint256.TryParse(txid, out uint256 trxid))
            {
                throw new ArgumentException(nameof(txid));
            }

            WalletAccountReference accountReference = this.GetWalletAccountReference();

            Wallet    hdWallet  = this.walletManager.WalletRepository.GetWallet(accountReference.WalletName);
            HdAccount hdAccount = this.walletManager.WalletRepository.GetAccounts(hdWallet, accountReference.AccountName).First();

            IWalletAddressReadOnlyLookup addressLookup = this.walletManager.WalletRepository.GetWalletAddressLookup(accountReference.WalletName);

            bool IsChangeAddress(Script scriptPubKey)
            {
                return(addressLookup.Contains(scriptPubKey, out AddressIdentifier addressIdentifier) && addressIdentifier.AddressType == 1);
            }

            // Get the transaction from the wallet by looking into received and send transactions.
            List <TransactionData> receivedTransactions = this.walletManager.WalletRepository.GetTransactionOutputs(hdAccount, null, trxid, true)
                                                          .Where(td => !IsChangeAddress(td.ScriptPubKey)).ToList();
            List <TransactionData> sentTransactions = this.walletManager.WalletRepository.GetTransactionInputs(hdAccount, null, trxid, true).ToList();

            TransactionData firstReceivedTransaction = receivedTransactions.FirstOrDefault();
            TransactionData firstSendTransaction     = sentTransactions.FirstOrDefault();

            if (firstReceivedTransaction == null && firstSendTransaction == null)
            {
                throw new RPCServerException(RPCErrorCode.RPC_INVALID_ADDRESS_OR_KEY, "Invalid or non-wallet transaction id.");
            }

            uint256         blockHash = null;
            int?            blockHeight, blockIndex;
            DateTimeOffset  transactionTime;
            SpendingDetails spendingDetails = firstSendTransaction?.SpendingDetails;

            if (firstReceivedTransaction != null)
            {
                blockHeight     = firstReceivedTransaction.BlockHeight;
                blockIndex      = firstReceivedTransaction.BlockIndex;
                blockHash       = firstReceivedTransaction.BlockHash;
                transactionTime = firstReceivedTransaction.CreationTime;
            }
            else
            {
                blockHeight     = spendingDetails.BlockHeight;
                blockIndex      = spendingDetails.BlockIndex;
                blockHash       = spendingDetails.BlockHash;
                transactionTime = spendingDetails.CreationTime;
            }

            // Get the block containing the transaction (if it has been confirmed).
            ChainedHeaderBlock chainedHeaderBlock = null;

            if (blockHash != null)
            {
                this.ConsensusManager.GetOrDownloadBlocks(new List <uint256> {
                    blockHash
                }, b => { chainedHeaderBlock = b; });
            }

            Block       block = null;
            Transaction transactionFromStore = null;

            if (chainedHeaderBlock != null)
            {
                block = chainedHeaderBlock.Block;
                if (block != null)
                {
                    if (blockIndex == null)
                    {
                        blockIndex = block.Transactions.FindIndex(t => t.GetHash() == trxid);
                    }

                    transactionFromStore = block.Transactions[(int)blockIndex];
                }
            }

            bool   isGenerated;
            string hex;

            if (transactionFromStore != null)
            {
                transactionTime = Utils.UnixTimeToDateTime(chainedHeaderBlock.ChainedHeader.Header.Time);
                isGenerated     = transactionFromStore.IsCoinBase || transactionFromStore.IsCoinStake;
                hex             = transactionFromStore.ToHex();
            }
            else
            {
                isGenerated = false;
                hex         = null; // TODO get from mempool
            }

            var model = new GetTransactionModel
            {
                Confirmations   = blockHeight != null ? this.ConsensusManager.Tip.Height - blockHeight.Value + 1 : 0,
                Isgenerated     = isGenerated ? true : (bool?)null,
                BlockHash       = blockHash,
                BlockIndex      = blockIndex,
                BlockTime       = block?.Header.BlockTime.ToUnixTimeSeconds(),
                TransactionId   = uint256.Parse(txid),
                TransactionTime = transactionTime.ToUnixTimeSeconds(),
                TimeReceived    = transactionTime.ToUnixTimeSeconds(),
                Details         = new List <GetTransactionDetailsModel>(),
                Hex             = hex
            };

            // Send transactions details.
            if (spendingDetails != null)
            {
                Money feeSent = Money.Zero;
                if (firstSendTransaction != null)
                {
                    // Get the change.
                    long change = spendingDetails.Change.Sum(o => o.Amount);

                    Money inputsAmount  = new Money(sentTransactions.Sum(i => i.Amount));
                    Money outputsAmount = new Money(spendingDetails.Payments.Sum(p => p.Amount) + change);

                    feeSent = inputsAmount - outputsAmount;
                }

                var details = spendingDetails.Payments
                              .GroupBy(detail => detail.DestinationAddress)
                              .Select(p => new GetTransactionDetailsModel()
                {
                    Address     = p.Key,
                    Category    = GetTransactionDetailsCategoryModel.Send,
                    OutputIndex = p.First().OutputIndex,
                    Amount      = 0 - p.Sum(detail => detail.Amount.ToDecimal(MoneyUnit.BTC)),
                    Fee         = -feeSent.ToDecimal(MoneyUnit.BTC)
                });

                model.Details.AddRange(details);
            }

            // Get the ColdStaking script template if available.
            Dictionary <string, ScriptTemplate> templates = this.walletManager.GetValidStakingTemplates();
            ScriptTemplate coldStakingTemplate            = templates.ContainsKey("ColdStaking") ? templates["ColdStaking"] : null;

            // Receive transactions details.
            IScriptAddressReader scriptAddressReader = this.FullNode.NodeService <IScriptAddressReader>();

            foreach (TransactionData trxInWallet in receivedTransactions)
            {
                // Skip the details if the script pub key is cold staking.
                // TODO: Verify if we actually need this any longer, after changing the internals to recognize account type
                if (coldStakingTemplate != null && coldStakingTemplate.CheckScriptPubKey(trxInWallet.ScriptPubKey))
                {
                    continue;
                }

                GetTransactionDetailsCategoryModel category;

                if (isGenerated)
                {
                    category = model.Confirmations > this.FullNode.Network.Consensus.CoinbaseMaturity ? GetTransactionDetailsCategoryModel.Generate : GetTransactionDetailsCategoryModel.Immature;
                }
                else
                {
                    category = GetTransactionDetailsCategoryModel.Receive;
                }

                string address = scriptAddressReader.GetAddressFromScriptPubKey(this.FullNode.Network, trxInWallet.ScriptPubKey);

                model.Details.Add(new GetTransactionDetailsModel
                {
                    Address     = address,
                    Category    = category,
                    Amount      = trxInWallet.Amount.ToDecimal(MoneyUnit.BTC),
                    OutputIndex = trxInWallet.Index
                });
            }

            model.Amount = model.Details.Sum(d => d.Amount);
            model.Fee    = model.Details.FirstOrDefault(d => d.Category == GetTransactionDetailsCategoryModel.Send)?.Fee;

            return(model);
        }
 public ColdStakingDestinationReader(IScriptAddressReader scriptAddressReader) : base(scriptAddressReader)
 {
 }
 public SmartContractScriptAddressReader(IScriptAddressReader addressReader)
 {
     this.baseAddressReader = addressReader;
 }