private void OnClientRegWndClosed(object sender, EventArgs e)
        {
            ClientRegistrationWindow window = sender as ClientRegistrationWindow;

            window.Closed -= OnClientRegWndClosed;
            if (window.DialogResult != null && window.DialogResult.Value)
            {
                UserRegistrationPropertiesViewModel vm = window.DataContext
                                                         as UserRegistrationPropertiesViewModel;
                if (vm == null)
                {
                    throw new ArgumentException("Wrong object type");
                }
                User   client   = vm.Model;
                string password = vm.Password;
                client.PasswordHash = Sha256Hash.Calculate(password);
                registeredClient    = client;
                ProcessMissingFields(client);
                UserRegistrator registrator = new UserRegistrator(client,
                                                                  OnClientRegistered, OnError);
                progressWindow         = new UserRegistrationProgressWindow(registrator);
                progressWindow.Closed += OnRegistrationWindowClosed;
                progressWindow.Show();
            }
        }
Пример #2
0
        /// <exception cref="BlockStoreException"/>
        private void CreateNewStore(NetworkParameters networkParams, FileInfo file)
        {
            // Create a new block store if the file wasn't found or anything went wrong whilst reading.
            _blockMap.Clear();
            try
            {
                if (_stream != null)
                {
                    _stream.Dispose();
                }

                _stream = file.OpenWrite(); // Do not append, create fresh.
                _stream.Write(1);           // Version.
            }
            catch (IOException e1)
            {
                // We could not load a block store nor could we create a new one!
                throw new BlockStoreException(e1);
            }
            try
            {
                // Set up the genesis block. When we start out fresh, it is by definition the top of the chain.
                var genesis       = networkParams.GenesisBlock.CloneAsHeader();
                var storedGenesis = new StoredBlock(genesis, genesis.GetWork(), 0);
                _chainHead = storedGenesis.Header.Hash;
                _stream.Write(_chainHead.Bytes);
                Put(storedGenesis);
            }
            catch (IOException e)
            {
                throw new BlockStoreException(e);
            }
        }
Пример #3
0
        /// <summary>
        /// Adds a transaction to this block, with or without checking the sanity of doing so.
        /// <exception cref="VerificationException"></exception>
        /// </summary>
        /// <param name="transaction"></param>
        /// <param name="runSanityChecks"></param>
        public void addTransaction(Transaction transaction, bool runSanityChecks)
        {
            if (Transactions == null)
            {
                Transactions = new List <Transaction>();
            }

            transaction.SetParent(this);

            if (runSanityChecks)
            {
                if (Transactions.Count == 0 && !transaction.IsCoinBase)
                {
                    throw new VerificationException("Attempted to add a non-coinbase transaction as the first transaction: " + t);
                }

                if (Transactions.Count > 0 && transaction.IsCoinBase)
                {
                    throw new VerificationException("Attempted to add a coinbase transaction when there already is one: " + t);
                }
            }


            Transactions.Add(transaction);
            AdjustLength(Transactions.Count, transaction.Length);

            // Force a recalculation next time the values are needed.
            MerkleRoot = null;
            hash       = null;
        }
Пример #4
0
        public static void HasReferenceSemantics()
        {
            var firstArray = new byte[Sha256Hash.Length];
            var secondArray = new byte[Sha256Hash.Length];

            for (var i = 0; i < Sha256Hash.Length; i++)
            {
                firstArray[i] = (byte)i;
                secondArray[i] = (byte)i;
            }

            var firstHash = new Sha256Hash(firstArray);
            var secondHash = new Sha256Hash(secondArray);

            // Value equality
            Assert.Equal(firstHash, secondHash);
            Assert.True(firstHash.Equals(secondHash));
            Assert.Equal(firstHash.GetHashCode(), secondHash.GetHashCode());

            // Reference equality
            Assert.False(firstHash == secondHash);

            var hashSet = new HashSet<Sha256Hash> { firstHash };
            Assert.True(hashSet.Contains(secondHash));
        }
Пример #5
0
        public static void HasReferenceSemantics()
        {
            var firstArray  = new byte[Sha256Hash.Length];
            var secondArray = new byte[Sha256Hash.Length];

            for (var i = 0; i < Sha256Hash.Length; i++)
            {
                firstArray[i]  = (byte)i;
                secondArray[i] = (byte)i;
            }

            var firstHash  = new Sha256Hash(firstArray);
            var secondHash = new Sha256Hash(secondArray);

            // Value equality
            Assert.Equal(firstHash, secondHash);
            Assert.True(firstHash.Equals(secondHash));
            Assert.Equal(firstHash.GetHashCode(), secondHash.GetHashCode());

            // Reference equality
            Assert.False(firstHash == secondHash);

            var hashSet = new HashSet <Sha256Hash> {
                firstHash
            };

            Assert.True(hashSet.Contains(secondHash));
        }
Пример #6
0
 public TransactionOutPoint(NetworkParameters params, long index, Sha256Hash hash)
 {
     super(params);
     this.index = index;
     this.hash  = hash;
     length     = MESSAGE_LENGTH;
 }
Пример #7
0
        public WalletTransaction(Transaction transaction, Sha256Hash hash, Input[] inputs, Output[] outputs, Amount?fee, DateTimeOffset seenTime)
        {
            if (transaction == null)
            {
                throw new ArgumentNullException(nameof(transaction));
            }
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }
            if (inputs == null)
            {
                throw new ArgumentNullException(nameof(inputs));
            }
            if (outputs == null)
            {
                throw new ArgumentNullException(nameof(outputs));
            }

            Hash        = hash;
            Inputs      = inputs;
            Outputs     = outputs;
            Fee         = fee;
            Transaction = transaction;
            SeenTime    = seenTime;
        }
Пример #8
0
        public void Sha256Hash_GetHash_Empty()
        {
            IHash hashAlgo = new Sha256Hash();

            Action action = () => hashAlgo.GetHash(string.Empty);

            action.Should().Throw <ArgumentNullException>();
        }
Пример #9
0
        public void Sha256Hash_GetHash_Null_3()
        {
            IHash hashAlgo = new Sha256Hash();

            Action action = () => hashAlgo.GetHash(null as FileInfo);

            action.Should().Throw <ArgumentNullException>();
        }
Пример #10
0
            public OutPoint(Sha256Hash hash, uint index)
            {
                if (hash == null)
                    throw new ArgumentNullException(nameof(hash));

                Hash = hash;
                Index = index;
            }
Пример #11
0
        public static Block MarshalBlock(BlockDetails b)
        {
            var hash         = new Sha256Hash(b.Hash.ToByteArray());
            var height       = b.Height;
            var unixTime     = b.Timestamp;
            var transactions = b.Transactions.Select(MarshalWalletTransaction).ToList();

            return(new Block(hash, height, unixTime, transactions));
        }
Пример #12
0
 public UnspentOutput(Sha256Hash txHash, uint outputIndex, Amount amount, OutputScript pkScript, DateTimeOffset seenTime, bool isFromCoinbase)
 {
     TransactionHash = txHash;
     OutputIndex = outputIndex;
     Amount = amount;
     PkScript = pkScript;
     SeenTime = seenTime;
     IsFromCoinbase = IsFromCoinbase;
 }
 /// <exception cref="BlockStoreException"/>
 public StoredBlock Get(Sha256Hash hash)
 {
     lock (this)
     {
         StoredBlock block;
         _blockMap.TryGetValue(hash, out block);
         return block;
     }
 }
Пример #14
0
        public Block(Sha256Hash hash, int height, long unixTime, List<WalletTransaction> transactions)
        {
            if (transactions == null)
                throw new ArgumentNullException(nameof(transactions));

            Identity = new BlockIdentity(hash, height);
            Timestamp = DateTimeOffsetExtras.FromUnixTimeSeconds(unixTime);
            Transactions = transactions;
        }
Пример #15
0
        //throws VerificationException
        private void checkMerkleRoot()
        {
            Sha256Hash calculatedRoot = CalculateMerkleRoot();

            if (!calculatedRoot.Equals(MerkleRoot))
            {
                throw new VerificationException("Merkle hashes do not match: " + calculatedRoot + " vs " + MerkleRoot);
            }
        }
Пример #16
0
 public WalletTransaction(Transaction transaction, Sha256Hash hash, Input[] inputs, Output[] outputs, Amount? fee, DateTimeOffset seenTime)
 {
     Hash = hash;
     Inputs = inputs;
     Outputs = outputs;
     Fee = fee;
     Transaction = transaction;
     SeenTime = seenTime;
 }
Пример #17
0
 private string HashPassword(string password)
 {
     if (password != string.Empty)
     {
         password = Sha256Hash.Generate(passwordInput.Text);
         return(password);
     }
     return(string.Empty);
 }
Пример #18
0
        public static Block MarshalBlock(BlockDetails b)
        {
            var hash = new Sha256Hash(b.Hash.ToByteArray());
            var height = b.Height;
            var unixTime = b.Timestamp;
            var transactions = b.Transactions.Select(MarshalWalletTransaction).ToList();

            return new Block(hash, height, unixTime, transactions);
        }
Пример #19
0
 internal Sha256Hash CreateHash()
 {
     byte[] array = new byte[artifactSequence.Length];
     for (int i = 0; i < array.Length; i++)
     {
         array[i] = (byte)artifactSequence[i];
     }
     return(Sha256Hash.FromBytes(hasher.ComputeHash(array)));
 }
Пример #20
0
 /// <exception cref="BlockStoreException"/>
 public StoredBlock Get(Sha256Hash hash)
 {
     lock (this)
     {
         StoredBlock block;
         _blockMap.TryGetValue(hash, out block);
         return(block);
     }
 }
Пример #21
0
        public void Sha256Hash_GetHash_Valid_2()
        {
            IHash hashAlgo = new Sha256Hash();

            HashResult hashResult = hashAlgo.GetHash(Data.ExpectedHashFilePath);

            hashResult.Algorithm.Should().Be(Hashing.ExpectedSha256Algorithm);
            hashResult.Value.Should().Be(Hashing.ExpectedSha256Hash);
        }
Пример #22
0
        internal Sha256HashAsset CreateHashAsset(Sha256Hash hash)
        {
            var asset = ScriptableObject.CreateInstance <Sha256HashAsset>();

            asset.value._00_07 = hash._00_07;
            asset.value._08_15 = hash._08_15;
            asset.value._16_23 = hash._16_23;
            asset.value._24_31 = hash._24_31;
            return(asset);
        }
        public async Task <CheckUserCredentialsOperationResponse> Execute(CheckUserCredentialsOperationRequest request)
        {
            string passwordHash = Sha256Hash.Calculate(request.Password);

            var queryResult = await _userRepository.QuerySingleOrDefaultAsync(user => user.Email == request.Email && user.PasswordHash == passwordHash);

            return(new CheckUserCredentialsOperationResponse
            {
                IsCorrect = queryResult != null
            });
        }
Пример #24
0
        public static UnspentOutput MarshalUnspentOutput(FundTransactionResponse.Types.PreviousOutput o)
        {
            var txHash = new Sha256Hash(o.TransactionHash.ToByteArray());
            var outputIndex = o.OutputIndex;
            var amount = (Amount)o.Amount;
            var pkScript = OutputScript.ParseScript(o.PkScript.ToByteArray());
            var seenTime = DateTimeOffsetExtras.FromUnixTimeSeconds(o.ReceiveTime);
            var isFromCoinbase = o.FromCoinbase;

            return new UnspentOutput(txHash, outputIndex, amount, pkScript, seenTime, isFromCoinbase);
        }
Пример #25
0
        public static UnspentOutput MarshalUnspentOutput(FundTransactionResponse.Types.PreviousOutput o)
        {
            var txHash         = new Sha256Hash(o.TransactionHash.ToByteArray());
            var outputIndex    = o.OutputIndex;
            var amount         = (Amount)o.Amount;
            var pkScript       = OutputScript.ParseScript(o.PkScript.ToByteArray());
            var seenTime       = DateTimeOffsetExtras.FromUnixTimeSeconds(o.ReceiveTime);
            var isFromCoinbase = o.FromCoinbase;

            return(new UnspentOutput(txHash, outputIndex, amount, pkScript, seenTime, isFromCoinbase));
        }
Пример #26
0
        public void Sha256Hash_GetHash_Valid_1()
        {
            IHash hashAlgo = new Sha256Hash();

            using FileStream fileStream = new(Data.ExpectedHashFilePath, FileMode.Open, FileAccess.Read, FileShare.Read);

            HashResult hashResult = hashAlgo.GetHash(fileStream);

            hashResult.Algorithm.Should().Be(Hashing.ExpectedSha256Algorithm);
            hashResult.Value.Should().Be(Hashing.ExpectedSha256Hash);
        }
Пример #27
0
 public override StoredBlock Get(Sha256Hash hash)
 {
     using (locker.AcquireReaderLock())
     {
         StoredBlock block;
         if (store.TryGetValue(hash.ToString(), out block))
         {
             return(block);
         }
         return(null);
     }
 }
Пример #28
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="height"></param>
 /// <param name="hash"></param>
 /// <returns>True if the block height is either not a checkpoint, or is a checkpoint and the hash matches.</returns>
 public bool PassesCheckpoint(int height, Sha256Hash hash)
 {
     if (hash != null)
     {
         Sha256Hash checkpointHash;
         if (Checkpoints.TryGetValue(height, out checkpointHash))
         {
             return(checkpointHash.Equals(hash));
         }
     }
     return(true);
 }
Пример #29
0
        /// <summary>
        /// Writes the byte[] FileContent to the specified path.
        /// If no filename is set the property Filename will be used.
        /// </summary>
        /// <param name="path"></param>
        /// <param name="filename"></param>
        /// <param name="overwrite"></param>
        /// <returns></returns>
        public virtual async Task WriteFileAsync(string path,
                                                 FileSavingOption options = null,
                                                 string filename          = null,
                                                 bool overwrite           = false)
        {
            if (options != null)
            {
                switch (options.Option)
                {
                case FileSavingOptions.SavingTimestamp:
                    Subfolder = DateTime.Now.ToString("yyyy-MM-dd_HHmmss_ff");
                    break;

                case FileSavingOptions.FirstTwoHashCharacters:
                    Subfolder = Sha256Hash?.Substring(0, 2);
                    break;

                case FileSavingOptions.EmailAccount:
                    Subfolder = options.EmailAccount;
                    break;
                }
            }

            // check if path is really a dir and not a filepath
            if (File.Exists(path))
            {
                // if the path is a filepath just take its directory
                path = Path.GetDirectoryName(path);
            }

            var fullPath = Path.Combine(path, Subfolder);

            // create path if it doesn't exist yet
            if (!Directory.Exists(fullPath))
            {
                Directory.CreateDirectory(fullPath);
            }

            filename = filename.IsNullOrEmpty() ? Filename : filename;

            var fullFilename = Path.Combine(fullPath, filename);

            if (!File.Exists(fullFilename) || overwrite)
            {
                using (var fs = new FileStream(fullFilename, FileMode.Create,
                                               FileAccess.Write, FileShare.None,
                                               bufferSize: 4096, useAsync: true))
                {
                    await fs.WriteAsync(FileContent, 0, FileContent.Length);
                }
                FullPath = fullFilename;
            }
        }
Пример #30
0
        public void Login()
        {
            var mock = new Mock <IVtsWebService>();

            mock.Setup(c => c.AuthenticateUser(It.IsAny <string>(), It.IsAny <string>())).
            Returns((string login, string passwdHash) => new UserDto()
            {
                Login = login, PasswordHash = passwdHash
            });
            UserController controller = new UserController(mock.Object);
            var            t          = controller.Signin("dummy", Sha256Hash.Calculate("dummy"), "Ru");

            Assert.IsInstanceOfType(t, typeof(RedirectToRouteResult));
        }
Пример #31
0
        /// <summary>
        /// Action uset lo log in a user after he has entered his credentials.
        /// </summary>
        public ActionResult Signin(string emailOrLogin, string password, string language)
        {
            string  passwordHash = Sha256Hash.Calculate(password);
            UserDto user         = service.AuthenticateUser(emailOrLogin, passwordHash);

            if (user == null)
            {
                TempData["LogonFailed"] = true;
                return(View("Logon"));
            }
            Session["User"] = UserAssembler.FromDtoToDomainObject(user);
            Session["Lang"] = LangConverter.Convert(language);
            return(RedirectToAction("Index", "Vehicles"));
        }
Пример #32
0
        public UnspentOutput(Sha256Hash txHash, uint outputIndex, Amount amount, OutputScript pkScript, DateTimeOffset seenTime, bool isFromCoinbase)
        {
            if (txHash == null)
                throw new ArgumentNullException(nameof(txHash));
            if (pkScript == null)
                throw new ArgumentNullException(nameof(pkScript));

            TransactionHash = txHash;
            OutputIndex = outputIndex;
            Amount = amount;
            PkScript = pkScript;
            SeenTime = seenTime;
            IsFromCoinbase = IsFromCoinbase;
        }
        /// <exception cref="BlockStoreException"/>
        public StoredBlock Get(Sha256Hash hash)
        {
            lock (this)
            {
                // Check the memory cache first.
                StoredBlock fromMem;
                if (_blockCache.TryGetValue(hash, out fromMem))
                {
                    return(fromMem);
                }

                if (_notFoundCache.TryGetValue(hash, out fromMem) && (fromMem == _notFoundMarker))
                {
                    return(null);
                }

                try
                {
                    var         fromDisk = GetRecord(hash);
                    StoredBlock block    = null;
                    if (fromDisk == null)
                    {
                        _notFoundCache[hash] = _notFoundMarker;
                        while (_notFoundCache.Count > 2050)
                        {
                            _notFoundCache.RemoveAt(0);
                        }
                    }
                    else
                    {
                        block             = fromDisk.ToStoredBlock(_params);
                        _blockCache[hash] = block;
                        while (_blockCache.Count > 2050)
                        {
                            _blockCache.RemoveAt(0);
                        }
                    }
                    return(block);
                }
                catch (IOException e)
                {
                    throw new BlockStoreException(e);
                }
                catch (ProtocolException e)
                {
                    throw new BlockStoreException(e);
                }
            }
        }
Пример #34
0
        public Block(Sha256Hash hash, int height, long unixTime, List <WalletTransaction> transactions)
        {
            if (hash == null)
            {
                throw new ArgumentNullException(nameof(hash));
            }
            if (transactions == null)
            {
                throw new ArgumentNullException(nameof(transactions));
            }

            Identity     = new BlockIdentity(hash, height);
            Timestamp    = DateTimeOffsetExtras.FromUnixTimeSeconds(unixTime);
            Transactions = transactions;
        }
Пример #35
0
        public static WalletTransaction MarshalWalletTransaction(TransactionDetails tx)
        {
            var transaction = Transaction.Deserialize(tx.Transaction.ToByteArray());
            var hash = new Sha256Hash(tx.Hash.ToByteArray());
            var inputs = tx.Debits
                .Select(i => new WalletTransaction.Input(i.PreviousAmount, new Account(i.PreviousAccount)))
                .ToArray();
            var outputs = tx.Outputs
                .Select((o, index) => MarshalWalletTransactionOutput(o, transaction.Outputs[index]))
                .ToArray();
            var fee = inputs.Length == transaction.Inputs.Length ? (Amount?)tx.Fee : null;
            var seenTime = DateTimeOffsetExtras.FromUnixTimeSeconds(tx.Timestamp);

            return new WalletTransaction(transaction, hash, inputs, outputs, fee, seenTime);
        }
Пример #36
0
 public TransactionOutPoint(NetworkParameters params, long index, Transaction fromTx)
 {
     super(params);
     this.index = index;
     if (fromTx != null)
     {
         this.hash   = fromTx.getHash();
         this.fromTx = fromTx;
     }
     else
     {
         // This happens when constructing the genesis block.
         hash = Sha256Hash.ZERO_HASH;
     }
     length = MESSAGE_LENGTH;
 }
        public static void ValidateBlock(Block block)
        {
            // first validate the Nonce matches the difficulty mask
            string mineHash = Sha256Hash.Hash(BitConverter.GetBytes(block.Nonce), block.PreviousBlockHash);

            if (!Regex.IsMatch(mineHash, block.DifficultyMask))
            {
                throw new Exception("Nonce does not match difficulty mask");
            }

            for (int i = 0; i < block.Transactions.Count; i++)
            {
                Transaction t = block.Transactions[i];
                TransactionValidatorService.ValidateTransaction(t);
            }
        }
Пример #38
0
        public void Should_Create_Genesis_Block()
        {
            // arrange
            var expected = Block.Genesis();

            // act
            var blockchain = new Blockchain();
            var actual     = blockchain.Chain.First();

            // assert
            blockchain.Chain.Should().HaveCount(1);
            actual.Should().NotBeNull();
            actual.Index.Should().Be(1);
            actual.Proof.Should().Be(new ProofOfWork(1));
            actual.PreviousHash.Should().Be(Sha256Hash.Of("Genesis"));
            actual.Transactions.Should().BeEmpty();
        }
Пример #39
0
        public void Should_Verify_Incorrect_Hash()
        {
            // arrange
            var genesis     = Block.Genesis();
            var secondBlock = MakeBlock(2, new Challenge().Solve(genesis.Proof), Sha256Hash.Of("invalid"), new List <Transaction>());
            var thirdBlock  = MakeBlock(3, secondBlock);
            var chain       = new List <Block>
            {
                genesis, secondBlock, thirdBlock
            };

            // act
            var actual = Blockchain.Validate(chain);

            // assert
            actual.Should().BeFalse();
        }
Пример #40
0
        public void FromGenesisPoW()
        {
            Core core = new Core();

            EcdsaKeyPair genesisWalletKp = new EcdsaKeyPair(Globals.Keys.GenesisPrivateKey);
            EcdsaKeyPair otherKp         = new EcdsaKeyPair();

            Block genesis = core.GenesisBlock;

            // find nonce for nextBlock
            Regex difficultyTestRegex = new Regex(genesis.DifficultyMask);

            UInt16 testNonce = 0;

            while (true)
            {
                string mineHash = Sha256Hash.Hash(BitConverter.GetBytes(testNonce), genesis.PreviousBlockHash);

                if (difficultyTestRegex.IsMatch(mineHash))
                {
                    break;
                }

                testNonce++;
            }

            Block nextBlock = BlockFactory.GenerateBlock(genesisWalletKp.Public);

            Transaction nextTransaction = new Transaction();

            nextTransaction.Inputs.Add(new TransactionInput {
                PreviousTransactionHash = genesis.Transactions[0].Hash, PreviousTransactionOutIndex = 0
            });
            nextTransaction.Outputs.Add(new TransactionOutput
            {
                Amount = 1M,
                To     = otherKp.Public
            });

            nextTransaction.Sign(genesisWalletKp.Private);

            nextBlock.Nonce = testNonce;
            nextBlock.Transactions.Add(nextTransaction);

            BlockValidatorService.ValidateBlock(nextBlock);
        }
Пример #41
0
        public WalletTransaction(Transaction transaction, Sha256Hash hash, Input[] inputs, Output[] outputs, Amount? fee, DateTimeOffset seenTime)
        {
            if (transaction == null)
                throw new ArgumentNullException(nameof(transaction));
            if (hash == null)
                throw new ArgumentNullException(nameof(hash));
            if (inputs == null)
                throw new ArgumentNullException(nameof(inputs));
            if (outputs == null)
                throw new ArgumentNullException(nameof(outputs));

            Hash = hash;
            Inputs = inputs;
            Outputs = outputs;
            Fee = fee;
            Transaction = transaction;
            SeenTime = seenTime;
        }
Пример #42
0
        public static void Run(string[] args)
        {
            Console.WriteLine("Connecting to node");
            var networkParams = NetworkParameters.ProdNet();

            using (var blockStore = new MemoryBlockStore(networkParams))
            {
                var chain = new BlockChain(networkParams, blockStore);
                var peer = new Peer(networkParams, new PeerAddress(IPAddress.Loopback), chain);
                peer.Connect();
                new Thread(() => peer.Run(CancellationToken.None)).Start();

                var blockHash = new Sha256Hash(args[0]);
                var future = peer.BeginGetBlock(blockHash, null, null);
                Console.WriteLine("Waiting for node to send us the requested block: " + blockHash);
                var block = peer.EndGetBlock(future);
                Console.WriteLine(block);
                peer.Disconnect();
            }
        }
Пример #43
0
        public static WalletTransaction MarshalWalletTransaction(TransactionDetails tx)
        {
            var transaction = Transaction.Deserialize(tx.Transaction.ToByteArray());
            var hash = new Sha256Hash(tx.Hash.ToByteArray());
            var inputs = tx.Debits
                .Select(i => new WalletTransaction.Input(i.PreviousAmount, new Account(i.PreviousAccount)))
                .ToArray();
            // There are two kinds of transactions to care about when choosing which outputs
            // should be created: transactions created by other wallets (inputs.Length == 0)
            // and those that spend controlled outputs from this wallet (inputs.Length != 0).
            // If the transaction was created by this wallet, then all outputs (both controlled
            // and uncontrolled) should be included.  Otherwise, uncontrolled outputs can be
            // ignored since they are not relevant (they could be change outputs for the other
            // wallet or outputs created for another unrelated wallet).
            var outputs = inputs.Length == 0
                ? tx.Credits.Select((o, i) => MarshalControlledOutput(o, transaction.Outputs[i])).ToArray()
                : MarshalCombinedOutputs(transaction, tx.Credits.GetEnumerator());
            var fee = inputs.Length == transaction.Inputs.Length ? (Amount?)tx.Fee : null;
            var seenTime = DateTimeOffsetExtras.FromUnixTimeSeconds(tx.Timestamp);

            return new WalletTransaction(transaction, hash, inputs, outputs, fee, seenTime);
        }
Пример #44
0
        /// <summary>
        /// Begins synchronization of the client with the remote wallet process.
        /// A delegate must be passed to be connected to the wallet's ChangesProcessed event to avoid
        /// a race where additional notifications are processed in the sync task before the caller
        /// can connect the event.  The caller is responsible for disconnecting the delegate from the
        /// event handler when finished.
        /// </summary>
        /// <param name="walletEventHandler">Event handler for changes to wallet as new transactions are processed.</param>
        /// <returns>The synced Wallet and the Task that is keeping the wallet in sync.</returns>
        public async Task<Tuple<Wallet, Task>> Synchronize(EventHandler<Wallet.ChangesProcessedEventArgs> walletEventHandler)
        {
            if (walletEventHandler == null)
                throw new ArgumentNullException(nameof(walletEventHandler));

            TransactionNotifications notifications;
            Task notificationsTask;

            // TODO: Initialization requests need timeouts.

            // Loop until synchronization did not race on a reorg.
            while (true)
            {
                // Begin receiving notifications for new and removed wallet transactions before
                // old transactions are downloaded.  Any received notifications are saved to
                // a buffer and are processed after GetAllTransactionsAsync is awaited.
                notifications = new TransactionNotifications(_channel, _tokenSource.Token);
                notificationsTask = notifications.ListenAndBuffer();

                var networkTask = NetworkAsync();

                // Concurrently download transaction history and account properties.
                var txSetTask = GetTransactionsAsync(Wallet.MinRecentTransactions, Wallet.NumRecentBlocks);
                var accountsTask = AccountsAsync();

                var networkResp = await networkTask;
                var activeBlockChain = BlockChainIdentity.FromNetworkBits(networkResp.ActiveNetwork);

                var txSet = await txSetTask;
                var rpcAccounts = await accountsTask;

                var lastAccountBlockHeight = rpcAccounts.CurrentBlockHeight;
                var lastAccountBlockHash = new Sha256Hash(rpcAccounts.CurrentBlockHash.ToByteArray());
                var lastTxBlock = txSet.MinedTransactions.LastOrDefault();
                if (lastTxBlock != null)
                {
                    var lastTxBlockHeight = lastTxBlock.Height;
                    var lastTxBlockHash = lastTxBlock.Hash;
                    if (lastTxBlockHeight > lastAccountBlockHeight ||
                        (lastTxBlockHeight == lastAccountBlockHeight && !lastTxBlockHash.Equals(lastAccountBlockHash)))
                    {
                        _tokenSource.Cancel();
                        continue;
                    }
                }

                // Read all received notifications thus far and determine if synchronization raced
                // on a chain reorganize.  Try again if so.
                IList<WalletChanges> transactionNotifications;
                if (notifications.Buffer.TryReceiveAll(out transactionNotifications))
                {
                    if (transactionNotifications.Any(r => r.DetachedBlocks.Count != 0))
                    {
                        _tokenSource.Cancel();
                        continue;
                    }

                    // Skip all attached block notifications that are in blocks lower than the
                    // block accounts notification.  If blocks exist at or past that height,
                    // the first's hash should equal that from the accounts notification.
                    //
                    // This ensures that both notifications contain data that is valid at this
                    // block.
                    var remainingNotifications = transactionNotifications
                        .SelectMany(r => r.AttachedBlocks)
                        .SkipWhile(b => b.Height < lastAccountBlockHeight)
                        .ToList();
                    if (remainingNotifications.Count != 0)
                    {
                        if (!remainingNotifications[0].Hash.Equals(lastAccountBlockHash))
                        {
                            _tokenSource.Cancel();
                            continue;
                        }
                    }

                    // TODO: Merge remaining notifications with the transaction set.
                    // For now, be lazy and start the whole sync over.
                    if (remainingNotifications.Count > 1)
                    {
                        _tokenSource.Cancel();
                        continue;
                    }
                }

                var accounts = rpcAccounts.Accounts.ToDictionary(
                    a => new Account(a.AccountNumber),
                    a => new AccountProperties
                    {
                        AccountName = a.AccountName,
                        TotalBalance = a.TotalBalance,
                        // TODO: uncomment when added to protospec and implemented by wallet.
                        //ImmatureCoinbaseReward = a.ImmatureBalance,
                        ExternalKeyCount = a.ExternalKeyCount,
                        InternalKeyCount = a.InternalKeyCount,
                        ImportedKeyCount = a.ImportedKeyCount,
                    });
                var chainTip = new BlockIdentity(lastAccountBlockHash, lastAccountBlockHeight);
                var wallet = new Wallet(activeBlockChain, txSet, accounts, chainTip);
                wallet.ChangesProcessed += walletEventHandler;

                var syncTask = Task.Run(async () =>
                {
                    var client = WalletService.NewClient(_channel);
                    var accountsStream = client.AccountNotifications(new AccountNotificationsRequest(), cancellationToken: _tokenSource.Token);
                    var accountChangesTask = accountsStream.ResponseStream.MoveNext();
                    var txChangesTask = notifications.Buffer.OutputAvailableAsync();
                    while (true)
                    {
                        var completedTask = await Task.WhenAny(accountChangesTask, txChangesTask);
                        if (!await completedTask)
                        {
                            break;
                        }
                        if (completedTask == accountChangesTask)
                        {
                            var accountProperties = accountsStream.ResponseStream.Current;
                            var account = new Account(accountProperties.AccountNumber);
                            wallet.UpdateAccountProperties(account, accountProperties.AccountName,
                                accountProperties.ExternalKeyCount, accountProperties.InternalKeyCount,
                                accountProperties.ImportedKeyCount);
                            accountChangesTask = accountsStream.ResponseStream.MoveNext();
                        }
                        else if (completedTask == txChangesTask)
                        {
                            var changes = notifications.Buffer.Receive();
                            wallet.ApplyTransactionChanges(changes);
                        }
                    }

                    await notificationsTask;
                });

                return Tuple.Create(wallet, syncTask);
            }
        }
Пример #45
0
 /// <exception cref="IOException"/>
 /// <exception cref="BlockStoreException"/>
 private void Load(FileInfo file)
 {
     _log.InfoFormat("Reading block store from {0}", file);
     using (var input = file.OpenRead())
     {
         // Read a version byte.
         var version = input.Read();
         if (version == -1)
         {
             // No such file or the file was empty.
             throw new FileNotFoundException(file.Name + " does not exist or is empty");
         }
         if (version != 1)
         {
             throw new BlockStoreException("Bad version number: " + version);
         }
         // Chain head pointer is the first thing in the file.
         var chainHeadHash = new byte[32];
         if (input.Read(chainHeadHash) < chainHeadHash.Length)
             throw new BlockStoreException("Truncated block store: cannot read chain head hash");
         _chainHead = new Sha256Hash(chainHeadHash);
         _log.InfoFormat("Read chain head from disk: {0}", _chainHead);
         var now = Environment.TickCount;
         // Rest of file is raw block headers.
         var headerBytes = new byte[Block.HeaderSize];
         try
         {
             while (true)
             {
                 // Read a block from disk.
                 if (input.Read(headerBytes) < 80)
                 {
                     // End of file.
                     break;
                 }
                 // Parse it.
                 var b = new Block(_params, headerBytes);
                 // Look up the previous block it connects to.
                 var prev = Get(b.PrevBlockHash);
                 StoredBlock s;
                 if (prev == null)
                 {
                     // First block in the stored chain has to be treated specially.
                     if (b.Equals(_params.GenesisBlock))
                     {
                         s = new StoredBlock(_params.GenesisBlock.CloneAsHeader(), _params.GenesisBlock.GetWork(), 0);
                     }
                     else
                     {
                         throw new BlockStoreException("Could not connect " + b.Hash + " to " + b.PrevBlockHash);
                     }
                 }
                 else
                 {
                     // Don't try to verify the genesis block to avoid upsetting the unit tests.
                     b.VerifyHeader();
                     // Calculate its height and total chain work.
                     s = prev.Build(b);
                 }
                 // Save in memory.
                 _blockMap[b.Hash] = s;
             }
         }
         catch (ProtocolException e)
         {
             // Corrupted file.
             throw new BlockStoreException(e);
         }
         catch (VerificationException e)
         {
             // Should not be able to happen unless the file contains bad blocks.
             throw new BlockStoreException(e);
         }
         var elapsed = Environment.TickCount - now;
         _log.InfoFormat("Block chain read complete in {0}ms", elapsed);
     }
 }
Пример #46
0
 /// <exception cref="BlockStoreException"/>
 private void CreateNewStore(NetworkParameters @params, FileInfo file)
 {
     // Create a new block store if the file wasn't found or anything went wrong whilst reading.
     _blockMap.Clear();
     try
     {
         if (_stream != null)
         {
             _stream.Dispose();
         }
         _stream = file.OpenWrite(); // Do not append, create fresh.
         _stream.Write(1); // Version.
     }
     catch (IOException e1)
     {
         // We could not load a block store nor could we create a new one!
         throw new BlockStoreException(e1);
     }
     try
     {
         // Set up the genesis block. When we start out fresh, it is by definition the top of the chain.
         var genesis = @params.GenesisBlock.CloneAsHeader();
         var storedGenesis = new StoredBlock(genesis, genesis.GetWork(), 0);
         _chainHead = storedGenesis.Header.Hash;
         _stream.Write(_chainHead.Bytes);
         Put(storedGenesis);
     }
     catch (IOException e)
     {
         throw new BlockStoreException(e);
     }
 }
Пример #47
0
 /// <exception cref="BlockStoreException"/>
 public void SetChainHead(StoredBlock chainHead)
 {
     lock (this)
     {
         try
         {
             _chainHead = chainHead.Header.Hash;
             // Write out new hash to the first 32 bytes of the file past one (first byte is version number).
             _stream.Seek(1, SeekOrigin.Begin);
             var bytes = _chainHead.Bytes;
             _stream.Write(bytes, 0, bytes.Length);
         }
         catch (IOException e)
         {
             throw new BlockStoreException(e);
         }
     }
 }
Пример #48
0
 public InventoryItem(ItemType type, Sha256Hash hash)
 {
     Type = type;
     Hash = hash;
 }
 /// <exception cref="BlockStoreException"/>
 /// <exception cref="IOException"/>
 /// <exception cref="ProtocolException"/>
 private Record GetRecord(Sha256Hash hash)
 {
     var startPos = _channel.Position;
     // Use our own file pointer within the tight loop as updating channel positions is really expensive.
     var pos = startPos;
     var record = new Record();
     do
     {
         if (!record.Read(_channel, pos, _buf))
             throw new IOException("Failed to read buffer");
         if (record.GetHeader(_params).Hash.Equals(hash))
         {
             // Found it. Update file position for next time.
             _channel.Position = pos;
             return record;
         }
         // Did not find it.
         if (pos == 1 + 32)
         {
             // At the start so wrap around to the end.
             pos = _channel.Length - Record.Size;
         }
         else
         {
             // Move backwards.
             pos = pos - Record.Size;
             Debug.Assert(pos >= 1 + 32, pos.ToString());
         }
     } while (pos != startPos);
     // Was never stored.
     _channel.Position = pos;
     return null;
 }
Пример #50
0
        public static Transaction Deserialize(byte[] rawTransaction)
        {
            if (rawTransaction == null)
                throw new ArgumentNullException(nameof(rawTransaction));

            int version;
            Input[] inputs;
            Output[] outputs;
            uint lockTime;

            var cursor = new ByteCursor(rawTransaction);

            try
            {
                version = cursor.ReadInt32();
                var inputCount = cursor.ReadCompact();
                if (inputCount > TransactionRules.MaxInputs)
                {
                    var reason = $"Input count {inputCount} exceeds maximum value {TransactionRules.MaxInputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                inputs = new Input[inputCount];
                for (int i = 0; i < (int)inputCount; i++)
                {
                    var previousHash = new Sha256Hash(cursor.ReadBytes(Sha256Hash.Length));
                    var previousIndex = cursor.ReadUInt32();
                    var previousOutPoint = new OutPoint(previousHash, previousIndex);
                    var signatureScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    var sequence = cursor.ReadUInt32();
                    inputs[i] = new Input(previousOutPoint, signatureScript, sequence);
                }
                var outputCount = cursor.ReadCompact();
                if (outputCount > TransactionRules.MaxOutputs)
                {
                    var reason = $"Output count {outputCount} exceeds maximum value {TransactionRules.MaxOutputs}";
                    throw new EncodingException(typeof(Transaction), cursor, reason);
                }
                outputs = new Output[outputCount];
                for (int i = 0; i < (int)outputCount; i++)
                {
                    var amount = (Amount)cursor.ReadInt64();
                    var pkScript = cursor.ReadVarBytes(TransactionRules.MaxPayload);
                    outputs[i] = new Output(amount, pkScript);
                }
                lockTime = cursor.ReadUInt32();
            }
            catch (Exception ex) when (!(ex is EncodingException))
            {
                throw new EncodingException(typeof(Transaction), cursor, ex);
            }

            return new Transaction(version, inputs, outputs, lockTime);
        }
Пример #51
0
 public OutPoint(Sha256Hash hash, uint index)
 {
     Hash = hash;
     Index = index;
 }
        /// <exception cref="BlockStoreException"/>
        public StoredBlock Get(Sha256Hash hash)
        {
            lock (this)
            {
                // Check the memory cache first.
                StoredBlock fromMem;
                if (_blockCache.TryGetValue(hash, out fromMem))
                {
                    return fromMem;
                }
                if (_notFoundCache.TryGetValue(hash, out fromMem) && fromMem == _notFoundMarker)
                {
                    return null;
                }

                try
                {
                    var fromDisk = GetRecord(hash);
                    StoredBlock block = null;
                    if (fromDisk == null)
                    {
                        _notFoundCache[hash] = _notFoundMarker;
                        while (_notFoundCache.Count > 2050)
                        {
                            _notFoundCache.RemoveAt(0);
                        }
                    }
                    else
                    {
                        block = fromDisk.ToStoredBlock(_params);
                        _blockCache[hash] = block;
                        while (_blockCache.Count > 2050)
                        {
                            _blockCache.RemoveAt(0);
                        }
                    }
                    return block;
                }
                catch (IOException e)
                {
                    throw new BlockStoreException(e);
                }
                catch (ProtocolException e)
                {
                    throw new BlockStoreException(e);
                }
            }
        }
 /// <exception cref="BlockStoreException"/>
 public void SetChainHead(StoredBlock chainHead)
 {
     lock (this)
     {
         try
         {
             _chainHead = chainHead.Header.Hash;
             // Write out new hash to the first 32 bytes of the file past one (first byte is version number).
             var originalPos = _channel.Position;
             _channel.Position = 1;
             var bytes = _chainHead.Bytes;
             _channel.Write(bytes, 0, bytes.Length);
             _channel.Position = originalPos;
         }
         catch (IOException e)
         {
             throw new BlockStoreException(e);
         }
     }
 }
 /// <exception cref="BlockStoreException"/>
 private void CreateNewStore(NetworkParameters @params, FileInfo file)
 {
     // Create a new block store if the file wasn't found or anything went wrong whilst reading.
     _blockCache.Clear();
     try
     {
         if (_channel != null)
         {
             _channel.Dispose();
             _channel = null;
         }
         if (file.Exists)
         {
             try
             {
                 file.Delete();
             }
             catch (IOException)
             {
                 throw new BlockStoreException("Could not delete old store in order to recreate it");
             }
         }
         _channel = file.Create(); // Create fresh.
         _channel.Write(_fileFormatVersion);
     }
     catch (IOException e1)
     {
         // We could not load a block store nor could we create a new one!
         throw new BlockStoreException(e1);
     }
     try
     {
         // Set up the genesis block. When we start out fresh, it is by definition the top of the chain.
         var genesis = @params.GenesisBlock.CloneAsHeader();
         var storedGenesis = new StoredBlock(genesis, genesis.GetWork(), 0);
         _chainHead = storedGenesis.Header.Hash;
         _channel.Write(_chainHead.Bytes);
         Put(storedGenesis);
     }
     catch (IOException e)
     {
         throw new BlockStoreException(e);
     }
 }
 /// <exception cref="IOException"/>
 /// <exception cref="BlockStoreException"/>
 private void Load(FileInfo file)
 {
     _log.InfoFormat("Reading block store from {0}", file);
     if (_channel != null)
     {
         _channel.Dispose();
     }
     _channel = file.OpenRead();
     try
     {
         // Read a version byte.
         var version = _channel.Read();
         if (version == -1)
         {
             // No such file or the file was empty.
             throw new FileNotFoundException(file.Name + " does not exist or is empty");
         }
         if (version != _fileFormatVersion)
         {
             throw new BlockStoreException("Bad version number: " + version);
         }
         // Chain head pointer is the first thing in the file.
         var chainHeadHash = new byte[32];
         if (_channel.Read(chainHeadHash) < chainHeadHash.Length)
             throw new BlockStoreException("Truncated store: could not read chain head hash.");
         _chainHead = new Sha256Hash(chainHeadHash);
         _log.InfoFormat("Read chain head from disk: {0}", _chainHead);
         _channel.Position = _channel.Length - Record.Size;
     }
     catch (IOException)
     {
         _channel.Close();
         throw;
     }
     catch (BlockStoreException)
     {
         _channel.Close();
         throw;
     }
 }