Example #1
0
 public bool SaveTransaction(Transaction tx)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             if (tx.Inputs.Any(p => !coins.Contains(p) || coins[p].State.HasFlag(CoinState.Spent) || !coins[p].State.HasFlag(CoinState.Confirmed)))
             {
                 return(false);
             }
             foreach (CoinReference input in tx.Inputs)
             {
                 coins[input].State |= CoinState.Spent;
                 coins[input].State &= ~CoinState.Confirmed;
             }
             for (ushort i = 0; i < tx.Outputs.Length; i++)
             {
                 AddressState state = CheckAddressState(tx.Outputs[i].ScriptHash);
                 if (state.HasFlag(AddressState.InWallet))
                 {
                     Coin coin = new Coin
                     {
                         Reference = new CoinReference
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = i
                         },
                         Output = tx.Outputs[i],
                         State  = CoinState.Unconfirmed
                     };
                     if (state.HasFlag(AddressState.WatchOnly))
                     {
                         coin.State |= CoinState.WatchOnly;
                     }
                     coins.Add(coin);
                 }
             }
             if (tx is ClaimTransaction)
             {
                 foreach (CoinReference claim in ((ClaimTransaction)tx).Claims)
                 {
                     coins[claim].State |= CoinState.Claimed;
                     coins[claim].State &= ~CoinState.Confirmed;
                 }
             }
             changeset = coins.GetChangeSet();
             OnSaveTransaction(tx, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
     return(true);
 }
Example #2
0
 private void ProcessNewBlock(Block block)
 {
     Coin[] changeset;
     lock (contracts)
         lock (coins)
         {
             foreach (Transaction tx in block.Transactions)
             {
                 for (ushort index = 0; index < tx.Outputs.Length; index++)
                 {
                     TransactionOutput output = tx.Outputs[index];
                     AddressState      state  = CheckAddressState(output.ScriptHash);
                     if (state.HasFlag(AddressState.InWallet))
                     {
                         CoinReference key = new CoinReference
                         {
                             PrevHash  = tx.Hash,
                             PrevIndex = index
                         };
                         if (coins.Contains(key))
                         {
                             coins[key].State |= CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Add(new Coin
                             {
                                 Reference = key,
                                 Output    = output,
                                 State     = CoinState.Confirmed
                             });
                         }
                         if (state.HasFlag(AddressState.WatchOnly))
                         {
                             coins[key].State |= CoinState.WatchOnly;
                         }
                     }
                 }
             }
             foreach (Transaction tx in block.Transactions)
             {
                 foreach (CoinReference input in tx.Inputs)
                 {
                     if (coins.Contains(input))
                     {
                         if (coins[input].Output.AssetId.Equals(Blockchain.SystemShare.Hash))
                         {
                             coins[input].State |= CoinState.Spent | CoinState.Confirmed;
                         }
                         else
                         {
                             coins.Remove(input);
                         }
                     }
                 }
             }
             foreach (ClaimTransaction tx in block.Transactions.OfType <ClaimTransaction>())
             {
                 foreach (CoinReference claim in tx.Claims)
                 {
                     if (coins.Contains(claim))
                     {
                         coins.Remove(claim);
                     }
                 }
             }
             current_height++;
             changeset = coins.GetChangeSet();
             OnProcessNewBlock(block, changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Added), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Changed), changeset.Where(p => ((ITrackable <CoinReference>)p).TrackState == TrackState.Deleted));
             coins.Commit();
         }
     if (changeset.Length > 0)
     {
         BalanceChanged?.Invoke(this, EventArgs.Empty);
     }
 }