Exemple #1
0
        public override void Bind(Instance r)
        {
            WaitQuorum(r, MessageType.Propose, msgs =>
            {
                var x = PickMostFrequentValue(
                    msgs.Where(m => Archiver.CanCommit(m.Value))
                    );

                var v = x.Count > r.Proposers.Count / 2 ? x.Value : null;

                Broadcast(r, MessageType.Select, v);
            });

            WaitQuorum(r, MessageType.Select, msgs =>
            {
                var x = PickMostFrequentValue(msgs.Where(m => m.Value != null));

                if (x.Count >= f + 1)
                {
                    Terminate(r, x.Value);
                    Proposer.Reset();
                }
                else
                {
                    if (x.Count > 0)
                    {
                        Proposer.Set(x.Value);
                    }
                    else
                    {
                        Proposer.Reset();
                    }
                }
            });
        }
Exemple #2
0
        private void BindAsAccepter(Instance r)
        {
            WaitMessage(r, MessageType.Propose, msg =>
            {
                var n = (long)msg.Value;

                if (n > minNumber)
                {
                    minNumber = n;
                    SendTo(msg.Source, r, MessageType.Ack, accepted);
                }
                else
                {
                    SendTo(msg.Source, r, MessageType.Nack, minNumber);
                }
            });

            WaitMessage(r, MessageType.Select, msg =>
            {
                var x = msg.Value as NumberedValue;

                if (x.Number >= minNumber && Archiver.CanCommit(x.Value))
                {
                    accepted = x;
                    SendTo(msg.Source, r, MessageType.Accept, x);
                }
            });

            WaitMessage(r, MessageType.Decide, msg =>
            {
                var x = msg.Value as NumberedValue;
                Terminate(r, x);
            });
        }
Exemple #3
0
        private void BindAsCoordinator(Instance r)
        {
            WaitQuorum(r, MessageType.Propose, msgs =>
            {
                var v = PickMostRecentValue(
                    msgs.Where(m => Archiver.CanCommit(m.Value))
                    );

                Broadcast(r, MessageType.Select, v);
            });

            WaitQuorum(r, MessageType.Ack, msgs =>
            {
                var v = PickMostRecentValue(msgs);
                Broadcast(r, MessageType.Decide, v);
                Terminate(r, v);
            });
        }
Exemple #4
0
        private void BindAsProposer(Instance r)
        {
            WaitQuorum(r, MessageType.Ack, msgs =>
            {
                var v = PickHighestNumberedValue(msgs)?.Value ?? Proposer.GetProposal();

                if (Archiver.CanCommit(v))
                {
                    var x = new NumberedValue(v, proposalNumber);
                    Broadcast(r, MessageType.Select, x);
                }
            });

            WaitMessage(r, MessageType.Nack, msg =>
            {
                if (msg.Value != null)
                {
                    var n = (long)msg.Value;
                    if (n > minNumber)
                    {
                        minNumber = Math.Max(n, minNumber);
                        if (RandomExtensions.Tryout(0.5))
                        {
                            Propose(r);
                        }
                    }
                }
            });

            WaitQuorum(r, MessageType.Accept, msgs =>
            {
                var m = msgs.Select(m => m.Value).Distinct();

                if (m.Count() == 1)
                {
                    var x = m.Single() as NumberedValue;
                    Terminate(r, x);
                    Broadcast(r, MessageType.Decide, x);
                }
            });
        }
Exemple #5
0
        private Block MineBlock(Instance r)
        {
            Block b     = null;
            var   found = false;
            var   v     = Proposer.GetProposal();
            var   c     = counter;

            while (!IsTerminated(r) && Archiver.CanCommit(v) && !found)
            {
                if (b == null || counter > c)
                {
                    c = counter;
                    var h = GetHeadFromLongestChain(v);
                    if (h == null)
                    {
                        break;
                    }
                    b = new Block(v, h);
                }
                b.IncrementPoW();
                found = b.VerifyPoW();
            }
            return(found ? b : null);
        }