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(); } }
/// <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); } }
/// <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; }
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)); }
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)); }
public TransactionOutPoint(NetworkParameters params, long index, Sha256Hash hash) { super(params); this.index = index; this.hash = hash; length = MESSAGE_LENGTH; }
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; }
public void Sha256Hash_GetHash_Empty() { IHash hashAlgo = new Sha256Hash(); Action action = () => hashAlgo.GetHash(string.Empty); action.Should().Throw <ArgumentNullException>(); }
public void Sha256Hash_GetHash_Null_3() { IHash hashAlgo = new Sha256Hash(); Action action = () => hashAlgo.GetHash(null as FileInfo); action.Should().Throw <ArgumentNullException>(); }
public OutPoint(Sha256Hash hash, uint index) { if (hash == null) throw new ArgumentNullException(nameof(hash)); Hash = hash; Index = index; }
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)); }
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; } }
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; }
//throws VerificationException private void checkMerkleRoot() { Sha256Hash calculatedRoot = CalculateMerkleRoot(); if (!calculatedRoot.Equals(MerkleRoot)) { throw new VerificationException("Merkle hashes do not match: " + calculatedRoot + " vs " + MerkleRoot); } }
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; }
private string HashPassword(string password) { if (password != string.Empty) { password = Sha256Hash.Generate(passwordInput.Text); return(password); } return(string.Empty); }
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); }
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))); }
/// <exception cref="BlockStoreException"/> public StoredBlock Get(Sha256Hash hash) { lock (this) { StoredBlock block; _blockMap.TryGetValue(hash, out block); return(block); } }
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); }
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 }); }
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); }
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)); }
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); }
public override StoredBlock Get(Sha256Hash hash) { using (locker.AcquireReaderLock()) { StoredBlock block; if (store.TryGetValue(hash.ToString(), out block)) { return(block); } return(null); } }
/// <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); }
/// <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; } }
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)); }
/// <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")); }
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); } } }
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; }
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); }
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); } }
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(); }
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(); }
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); }
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; }
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(); } }
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); }
/// <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); } }
/// <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); } }
/// <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); } }
/// <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); } } }
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; }
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); }
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; } }