public Chain(Chain copied, ObjectStream<ChainChange> changes) { if(changes == null) changes = new StreamObjectStream<ChainChange>(); AssertEmpty(changes); _Changes = changes; copied.Changes.Rewind(); foreach(var change in copied.Changes.Enumerate()) { if(_NextToProcess < copied._NextToProcess) { ProcessAndRecord(change, null); } else { _Changes.WriteNext(change); } } }
private void NeutralizeUnconfirmed(Chain chain, Account account) { var unconfirmed = account.GetInChain(chain, false).Where(e => e.Reason != AccountEntryReason.ChainBlockChanged); foreach(var e in unconfirmed) { account.PushAccountEntry(e.Neutralize()); } var confirmedCanceled = account.GetInChain(chain, true).Where(e => e.Reason == AccountEntryReason.ChainBlockChanged); foreach(var e in confirmedCanceled) { account.PushAccountEntry(e.Neutralize()); } }
public void Update(Chain chain) { NeutralizeUnconfirmed(chain, Confirmed); NeutralizeUnconfirmed(chain, Available); }
public bool Update(Chain chain, IndexedBlockStore store) { if(_CurrentChain == null || !chain.SameTip(_CurrentChain)) { List<ChainedBlock> unprocessed = null; Accounts.Update(chain); if(_CurrentChain == null) { _CurrentChain = chain.Clone(new StreamObjectStream<ChainChange>()); unprocessed = chain.ToEnumerable(false).ToList(); } else { var fork = _CurrentChain.SetTip(chain.Tip); unprocessed = _CurrentChain.EnumerateAfter(fork).ToList(); } foreach(var block in unprocessed) { ReceiveBlock(store.Get(block.HashBlock)); } return true; } return false; }
//Do not get all entries, but only the one you can generate with spent/unspent. public AccountEntry[] GetInChain(Chain chain, bool value) { Dictionary<OutPoint, AccountEntry> entries = new Dictionary<OutPoint, AccountEntry>(); foreach(var entry in AccountEntries) { if(entry.Block == null) continue; if(chain.Contains(entry.Block, false) == value) { if(entry.Reason == AccountEntryReason.Income && _Unspent.ContainsKey(entry.Spendable.OutPoint)) entries.AddOrReplace(entry.Spendable.OutPoint, entry); if(entry.Reason == AccountEntryReason.ChainBlockChanged && !_Unspent.ContainsKey(entry.Spendable.OutPoint)) entries.AddOrReplace(entry.Spendable.OutPoint, entry); } } return entries.Values.ToArray(); }
public Chain(Chain copied) : this(copied, null) { }
public bool SameTip(Chain chain) { return(Tip.HashBlock == chain.Tip.HashBlock); }
public ChainedBlock FindFork(Chain chain) { return(FindFork(chain.ToEnumerable(true).Select(o => o.HashBlock))); }
public void CanDownloadChain() { using(var server = new NodeServer(Network.Main)) { server.RegisterPeerTableRepository(PeerCache); CancellationTokenSource cancel = new CancellationTokenSource(); StreamObjectStream<ChainChange> changes = new StreamObjectStream<ChainChange>(new MemoryStream()); var chain = new Chain(changes); server.BuildChain(changes, cancel.Token); } }
//Do not get all entries, but only the one you can generate with spent/unspent. public AccountEntry[] GetInChain(Chain chain, bool value) { List<AccountEntry> entries = new List<AccountEntry>(); foreach(var entry in AccountEntries.Where(e => e.Reason != AccountEntryReason.ChainBlockChanged)) { if(entry.Block == null) continue; if(chain.Contains(entry.Block, false) == value) { entries.Add(entry); } } return entries.ToArray(); }
public bool SameTip(Chain chain) { return Tip.HashBlock == chain.Tip.HashBlock; }
public ChainedBlock FindFork(Chain chain) { return FindFork(chain.ToEnumerable(true).Select(o => o.HashBlock)); }