private ICoinsView RemoveNoLock(SmartCoin coin) { var coinsToRemove = DescendantOfAndSelfNoLock(coin); foreach (var toRemove in coinsToRemove) { if (!Coins.Remove(toRemove)) { SpentCoins.Remove(toRemove); } var removedCoinOutPoint = toRemove.OutPoint; // If we can find it in our outpoint to coins cache. if (TryGetSpenderSmartCoinsByOutPointNoLock(removedCoinOutPoint, out var coinsByOutPoint)) { // Go through all the coins of that cache where the coin is the coin we are wishing to remove. foreach (var coinByOutPoint in coinsByOutPoint.Where(x => x == toRemove)) { // Remove the coin from the set, and if the set becomes empty as a consequence remove the key too. if (CoinsByOutPoint[removedCoinOutPoint].Remove(coinByOutPoint) && !CoinsByOutPoint[removedCoinOutPoint].Any()) { CoinsByOutPoint.Remove(removedCoinOutPoint); } } } } InvalidateSnapshot = true; return(coinsToRemove); }
public bool TryAdd(SmartCoin coin) { var added = false; lock (Lock) { if (!SpentCoins.Contains(coin)) { added = Coins.Add(coin); if (added) { if (ClustersByScriptPubKey.TryGetValue(coin.ScriptPubKey, out var cluster)) { coin.Clusters = cluster; } else { ClustersByScriptPubKey.Add(coin.ScriptPubKey, coin.Clusters); } InvalidateSnapshot = true; } } } return(added); }
internal (ICoinsView toRemove, ICoinsView toAdd) Undo(uint256 txId) { lock (Lock) { var allCoins = AsAllCoinsViewNoLock(); var toRemove = new List <SmartCoin>(); var toAdd = new List <SmartCoin>(); // remove recursively the coins created by the transaction foreach (SmartCoin createdCoin in allCoins.CreatedBy(txId)) { toRemove.AddRange(Remove(createdCoin)); } // destroyed (spent) coins are now (unspent) foreach (SmartCoin destroyedCoin in allCoins.SpentBy(txId)) { if (SpentCoins.Remove(destroyedCoin)) { Coins.Add(destroyedCoin); toAdd.Add(destroyedCoin); } } InvalidateSnapshot = true; return(new CoinsView(toRemove), new CoinsView(toAdd)); } }
public void RemoveFromBlock(Height blockHeight) { lock (Lock) { var allCoins = AsAllCoinsViewNoLock(); foreach (var toRemove in allCoins.AtBlockHeight(blockHeight).ToList()) { var coinsToRemove = allCoins.DescendantOfAndSelf(toRemove).ToList(); foreach (var coin in coinsToRemove) { if (coin.Unspent) { if (Coins.Remove(coin)) { InvalidateSnapshot = true; } } else { SpentCoins.Remove(toRemove); } } } } }
public void TxQueryTestNet(string txInput) { try { // Create a client Client = new QBitNinjaClient(Network.TestNet); // Parse transaction id to NBitcoin.uint256 so the client can eat it var transactionId = uint256.Parse(txInput); // Query the transaction QBitNinja.Client.Models.GetTransactionResponse transactionResponse = Client.GetTransaction(transactionId).Result; // Extract Transaction Transaction = transactionResponse.Transaction; // Extract Recieved Coins: TxOut RecievedCoins = transactionResponse.ReceivedCoins; // Extract Spent Coins: TxIn SpentCoins = transactionResponse.SpentCoins; // Extract Fees Paid: Fee Fee = Transaction.GetFee(SpentCoins.ToArray()); //Count Block Confirmations Block = transactionResponse.Block.Confirmations; } catch (Exception ex) { Ex = ex; } }
private CoinsView AsSpentCoinsViewNoLock() { if (InvalidateSnapshot) { LatestCoinsSnapshot = Coins.ToHashSet(); // Creates a clone LatestSpentCoinsSnapshot = SpentCoins.ToHashSet(); // Creates a clone InvalidateSnapshot = false; } return(new CoinsView(LatestSpentCoinsSnapshot)); }
public void Spend(SmartCoin spentCoin, SmartTransaction tx) { spentCoin.SpenderTransaction = tx; lock (Lock) { if (Coins.Remove(spentCoin)) { InvalidateSnapshot = true; SpentCoins.Add(spentCoin); } } }
public bool TryAdd(SmartCoin coin) { var added = false; lock (Lock) { if (!SpentCoins.Contains(coin)) { added = Coins.Add(coin); if (added) { if (ClustersByScriptPubKey.TryGetValue(coin.ScriptPubKey, out var cluster)) { coin.Cluster = cluster; } else { ClustersByScriptPubKey.Add(coin.ScriptPubKey, coin.Cluster); } foreach (var spentOutPoint in coin.SpentOutputs) { var outPoint = spentOutPoint; var newCoinSet = new HashSet <SmartCoin> { coin }; // If we don't succeed to add a new entry to the dictionary. if (!CoinsByOutPoint.TryAdd(outPoint, newCoinSet)) { var previousCoinTxId = CoinsByOutPoint[outPoint].First().TransactionId; // Then check if we're in the same transaction as the previous coins in the dictionary are. if (coin.TransactionId == previousCoinTxId) { // If we are in the same transaction, then just add it to value set. CoinsByOutPoint[outPoint].Add(coin); } else { // If we aren't in the same transaction, then it's a conflict, so replace the old set with the new one. CoinsByOutPoint[outPoint] = newCoinSet; } } } InvalidateSnapshot = true; } } } return(added); }
public ICoinsView Remove(SmartCoin coin) { lock (Lock) { var coinsToRemove = DescendantOfAndSelfNoLock(coin); foreach (var toRemove in coinsToRemove) { if (!Coins.Remove(toRemove)) { if (SpentCoins.Remove(toRemove)) { // Clusters.Remove(toRemove); } } } InvalidateSnapshot = true; return(coinsToRemove); } }
public virtual void Commit() { Accounts.DeleteWhere((k, v) => !v.IsFrozen && v.Votes.Length == 0 && v.Balances.All(p => p.Value <= Fixed8.Zero)); UnspentCoins.DeleteWhere((k, v) => v.Items.All(p => p.HasFlag(CoinState.Spent))); SpentCoins.DeleteWhere((k, v) => v.Items.Count == 0); Blocks.Commit(Height); Transactions.Commit(Height); Accounts.Commit(Height); UnspentCoins.Commit(Height); SpentCoins.Commit(Height); Validators.Commit(Height); Assets.Commit(Height); Contracts.Commit(Height); Storages.Commit(Height); HeaderHashList.Commit(Height); ValidatorsCount.Commit(Height); BlockHashIndex.Commit(Height); HeaderHashIndex.Commit(Height); }
internal DynamicTableEntity ToEntity() { DynamicTableEntity entity = new DynamicTableEntity(); entity.ETag = "*"; entity.PartitionKey = PartitionKey; var locator = CreateBalanceLocator(); entity.RowKey = BalanceId + "-" + locator.ToString(true); entity.Properties.Add("s", new EntityProperty(SeenUtc)); Helper.SetEntityProperty(entity, "ss", Helper.SerializeList(SpentIndices.Select(e => new IntCompactVarInt(e)))); Helper.SetEntityProperty(entity, "a", Helper.SerializeList(SpentOutpoints)); if (SpentCoins != null) { Helper.SetEntityProperty(entity, "b", Helper.SerializeList(SpentCoins.Select(c => new Spendable(c.Outpoint, c.TxOut)))); } Helper.SetEntityProperty(entity, "c", Helper.SerializeList(ReceivedCoins.Select(e => new IntCompactVarInt(e.Outpoint.N)))); Helper.SetEntityProperty(entity, "d", Helper.SerializeList(ReceivedCoins.Select(e => e.TxOut))); var flags = (HasOpReturn ? "o" : "n") + (IsCoinbase ? "o" : "n"); entity.Properties.AddOrReplace("e", new EntityProperty(flags)); entity.Properties.AddOrReplace("f", new EntityProperty(Helper.Serialize(MatchedRules))); if (ColoredTransaction != null) { entity.Properties.AddOrReplace("g", new EntityProperty(ColoredTransaction.ToBytes())); } if (ScriptPubKey != null && !BalanceId.ContainsScript) { var bytes = ScriptPubKey.ToBytes(true); if (bytes.Length < 63000) { entity.Properties.Add("h", new EntityProperty(bytes)); } } if (CustomData != null) { Helper.SetEntityProperty(entity, "cu", Encoding.UTF8.GetBytes(CustomData)); } return(entity); }
public bool TryAdd(SmartCoin coin) { var added = false; lock (Lock) { if (!SpentCoins.Contains(coin)) { added = Coins.Add(coin); coin.RegisterToHdPubKey(); if (added) { foreach (var outPoint in coin.Transaction.Transaction.Inputs.Select(x => x.PrevOut)) { var newCoinSet = new HashSet <SmartCoin> { coin }; // If we don't succeed to add a new entry to the dictionary. if (!CoinsByOutPoint.TryAdd(outPoint, newCoinSet)) { var previousCoinTxId = CoinsByOutPoint[outPoint].First().TransactionId; // Then check if we're in the same transaction as the previous coins in the dictionary are. if (coin.TransactionId == previousCoinTxId) { // If we are in the same transaction, then just add it to value set. CoinsByOutPoint[outPoint].Add(coin); } else { // If we aren't in the same transaction, then it's a conflict, so replace the old set with the new one. CoinsByOutPoint[outPoint] = newCoinSet; } } } InvalidateSnapshot = true; } } } return(added); }
public void Spend(SmartCoin spentCoin) { lock (Lock) { if (Coins.Remove(spentCoin)) { InvalidateSnapshot = true; SpentCoins.Add(spentCoin); var createdCoins = CreatedByNoLock(spentCoin.SpenderTransactionId); foreach (var newCoin in createdCoins) { if (newCoin.AnonymitySet < PrivacyLevelThreshold) { spentCoin.Clusters.Merge(newCoin.Clusters); newCoin.Clusters = spentCoin.Clusters; ClustersByScriptPubKey.AddOrReplace(newCoin.ScriptPubKey, newCoin.Clusters); } } } } }
internal JObject ToJson() { var obj = new JObject(); if (BlockId != null) { obj.Add("Height", Height); obj.Add("BlockId", BlockId.ToString()); obj.Add("Proof", Encoders.Hex.EncodeData(this.Proof.ToBytes())); } obj.Add("AddedDate", AddedDate); obj.Add("UnconfirmedSeen", UnconfirmedSeen); obj.Add("Transaction", Encoders.Hex.EncodeData(this.Transaction.ToBytes())); if (this.ReceivedCoins != null) { obj.Add("ReceivedCoins", new JArray(ReceivedCoins.Select(c => ToJson(c)))); } if (this.SpentCoins != null) { obj.Add("SpentCoins", new JArray(SpentCoins.Select(c => ToJson(c)))); } return(obj); }
public Dictionary <ushort, SpentCoin> GetUnclaimed(UInt256 hash) { TransactionState tx_state = Transactions.TryGet(hash); if (tx_state == null) { return(null); } SpentCoinState coin_state = SpentCoins.TryGet(hash); if (coin_state != null) { return(coin_state.Items.ToDictionary(p => p.Key, p => new SpentCoin { Output = tx_state.Transaction.Outputs[p.Key], StartHeight = tx_state.BlockIndex, EndHeight = p.Value })); } else { return(new Dictionary <ushort, SpentCoin>()); } }