public bool Discard(Transaction tx) { if (this.CurrentState != State.Running) { return(false); } if (_hashMap.ContainsKey(tx.Hash)) { var chainName = _hashMap[tx.Hash]; _hashMap.Remove(tx.Hash); lock (_entries) { if (_entries.ContainsKey(chainName)) { var list = _entries[chainName]; list.RemoveAll(x => x.transaction.Hash == tx.Hash); } } Interlocked.Decrement(ref _size); OnTransactionRemoved?.Invoke(tx); return(true); } return(false); }
private void MintBlock(List <Transaction> transactions, Chain chain) { var hashes = new HashSet <Hash>(transactions.Select(tx => tx.Hash)); var isFirstBlock = chain.LastBlock == null; while (hashes.Count > 0) { var block = new Block(isFirstBlock ? 1 : (chain.LastBlock.Height + 1), chain.Address, Timestamp.Now, hashes, isFirstBlock ? Hash.Null : chain.LastBlock.Hash); try { chain.AddBlock(block, transactions, MinimumFee); } catch (InvalidTransactionException e) { var tx = transactions.First(x => x.Hash == e.Hash); Interlocked.Decrement(ref _size); hashes.Remove(e.Hash); lock (_rejections) { _rejections[e.Hash] = e.Message; } transactions.Remove(tx); OnTransactionFailed?.Invoke(tx); continue; } lock (_entries) { foreach (var tx in transactions) { _pendingSet.Remove(tx.Hash); } } foreach (var tx in transactions) { Interlocked.Decrement(ref _size); OnTransactionRemoved?.Invoke(tx); } break; } lock (_pendingBlocks) { _pendingBlocks.Remove(chain); } }