public Dep(BlockID block, List <BlockID> deps)
 {
     Block = block;
     Deps  = deps;
     Prev  = new BlockID();
 }
 public Dep(BlockID block, List <BlockID> deps, BlockID prev)
 {
     Block = block;
     Deps  = deps;
     Prev  = prev;
 }
 public Dep()
 {
     Block = new BlockID();
     Deps  = new List <BlockID>();
     Prev  = new BlockID();
 }
 public Dep(BlockID block)
 {
     Block = block;
     Deps  = new List <BlockID>();
     Prev  = new BlockID();
 }
 public BlockGraph(BlockID block, BlockID prev)
 {
     Block = block;
     Prev  = prev;
     Deps  = new List <Dep>();
 }
 public BlockGraph(BlockID block, List <Dep> deps, BlockID prev)
 {
     Block = block;
     Deps  = deps;
     Prev  = prev;
 }
 public BlockGraph()
 {
     Block = new BlockID();
     Deps  = new List <Dep>();
     Prev  = new BlockID();
 }
 public BlockGraph(BlockID block)
 {
     Block = block;
     Deps  = new List <Dep>();
     Prev  = new BlockID();
 }
        private List <IMessage> ProcessMessages(State s, Dictionary <IMessage, bool> processed, ulong sender, ulong receiver, BlockID origin, List <IMessage> msgs)
        {
            var out_ = new List <IMessage>();

            foreach (var msg in msgs)
            {
                if (processed.ContainsKey(msg) && processed[msg])
                {
                    continue;
                }
                var resp = ProcessMessage(s, sender, receiver, origin, msg);
                processed[msg] = true;
                if (resp != null)
                {
                    out_.Add(resp);
                }
            }
            for (var i = 0; i < out_.Count; i++)
            {
                var msg = out_[i];
                if (processed.ContainsKey(msg) && processed[msg])
                {
                    continue;
                }
                var resp = ProcessMessage(s, sender, receiver, origin, msg);
                processed[msg] = true;
                if (resp != null)
                {
                    out_.Add(resp);
                }
            }
            return(out_);
        }
        private IMessage ProcessMessage(State s, ulong sender, ulong receiver, BlockID origin, IMessage msg)
        {
            var(node, round) = msg.NodeRound();
            if (s.Data.ContainsKey(new Final(node, round)))
            {
                return(null);
            }
            var v = s.GetView(node, round);

            Debug.WriteLine($"Processing message from block block.id={origin} message={msg}");

            switch (msg)
            {
            case PrePrepare m:
                if (v != m.View)
                {
                    return(null);
                }
                var pp = new PrePrepared(node, round, m.View);
                if (s.Data.ContainsKey(pp))
                {
                    return(null);
                }
                ulong size = sender > receiver ? sender : receiver;
                // var b = s.GetBitSet(NodeCount, m);
                var b = s.GetBitSet((int)size, m);
                b.SetPrepare(sender);
                b.SetPrepare(receiver);
                if (s.Data == null)
                {
                    s.Data = new StateKV()
                    {
                        { pp, m }
                    };
                }
                else
                {
                    s.Data[pp] = m;
                }
                return(new Prepare(m.Hash, node, round, receiver, m.View));

            case Prepare m:
                if (v > m.View)
                {
                    return(null);
                }
                if (v < m.View)
                {
                    // b = s.GetBitSet(NodeCount, m.Pre());
                    b = s.GetBitSet((int)sender, m.Pre());
                    b.SetPrepare(m.Sender);
                    return(null);
                }
                // b = s.GetBitSet(NodeCount, m.Pre());
                b = s.GetBitSet((int)sender, m.Pre());
                b.SetPrepare(m.Sender);

                Debug.WriteLine($"Prepare count == {b.PrepareCount()}");

                if (b.PrepareCount() != Quorum2f1)
                {
                    return(null);
                }
                if (b.HasCommit(receiver))
                {
                    return(null);
                }
                b.SetCommit(receiver);
                var p = new Prepared(node, round, m.View);
                if (!s.Data.ContainsKey(p))
                {
                    if (s.Data == null)
                    {
                        s.Data = new StateKV()
                        {
                            { p, m.Hash }
                        };
                    }
                    else
                    {
                        s.Data[p] = m.Hash;
                    }
                }
                return(new Commit(m.Hash, node, round, receiver, m.View));

            case Commit m:
                if (v < m.View)
                {
                    return(null);
                }
                // b = s.GetBitSet(NodeCount, m.Pre());
                b = s.GetBitSet((int)sender, m.Pre());
                b.SetCommit(m.Sender);

                Debug.WriteLine($"Commit count == {b.CommitCount()}");

                if (b.CommitCount() != Quorum2f1)
                {
                    return(null);
                }
                var nr = new NodeRound(node, round);
                if (s.Final.ContainsKey(nr))
                {
                    return(null);
                }
                if (s.Final == null)
                {
                    s.Final = new Dictionary <NodeRound, string>()
                    {
                        { nr, m.Hash }
                    };
                }
                else
                {
                    s.Final[nr] = m.Hash;
                }
                Deliver(node, round, m.Hash);
                return(null);

            case ViewChange m:
                if (v > m.View)
                {
                    return(null);
                }
                Dictionary <ulong, string> vcs;
                var key = new ViewChanged(node, round, v);
                if (s.Data.ContainsKey(key))
                {
                    var val = s.Data[key];
                    vcs = (Dictionary <ulong, string>)val;
                }
                else
                {
                    vcs = new Dictionary <ulong, string>();
                    if (s.Data == null)
                    {
                        s.Data = new StateKV()
                        {
                            { key, vcs }
                        };
                    }
                    else
                    {
                        s.Data[key] = vcs;
                    }
                }
                vcs[m.Sender] = m.Hash;
                if (vcs.Count != Quorum2f1)
                {
                    return(null);
                }
                s.Data[new View(node, round)] = m.View;
                var hash = "";
                foreach (KeyValuePair <ulong, string> item in vcs)
                {
                    var hval = item.Value;
                    if (hval != "")
                    {
                        if (hash != "" && hval != hash)
                        {
                            Console.WriteLine($"Got multiple hashes in a view change node.id={node} round={round} hash={hash} hash.alt={hval}");
                        }
                        hash = hval;
                    }
                }
                return(new NewView(hash, node, round, receiver, m.View));

            case NewView m:
                if (v > m.View)
                {
                    return(null);
                }
                var viewKey = new Hnv(node, round, m.View);
                if (s.Data.ContainsKey(viewKey))
                {
                    return(null);
                }
                if (s.Data == null)
                {
                    s.Data = new StateKV();
                }
                s.Data[new View(node, round)] = m.View;
                var tval = origin.Round + s.Timeout + 5;
                if (!s.Timeouts.ContainsKey(tval))
                {
                    s.Timeouts[tval] = new List <Timeout>();
                }
                s.Timeouts[tval].Add(new Timeout(node, round, m.View));
                s.Data[viewKey] = true;
                return(new PrePrepare(m.Hash, node, round, m.View));

            default:
                throw new Exception($"blockmania: unknown message kind to process: {msg.Kind()}");
            }
        }
 public Entry(BlockID block, BlockID[] deps, BlockID prev)
 {
     Block = block;
     Deps  = deps;
     Prev  = prev;
 }
 public Entry(BlockID block, BlockID prev)
 {
     Block = block;
     Prev  = prev;
 }
 public Entry(BlockID prev)
 {
     Prev = prev;
 }