So many changes. Broken.
[invirt/third/libt4.git] / include / paxos.h
1 #ifndef paxos_h
2 #define paxos_h
3
4 #include "include/types.h"
5 #include "include/rpc/rpc.h"
6 #include "include/paxos_protocol.h"
7 #include "include/log.h"
8
9 using prepareres = paxos_protocol::prepareres;
10 using node_t = paxos_protocol::node_t;
11 using nodes_t = paxos_protocol::nodes_t;
12 using value_t = paxos_protocol::value_t;
13
14 class paxos_change {
15     public:
16         virtual void paxos_commit(unsigned instance, const value_t & v) = 0;
17         virtual ~paxos_change();
18 };
19
20 extern bool isamember(const node_t & m, const nodes_t & nodes);
21 extern bool majority(const nodes_t & l1, const nodes_t & l2);
22
23 class proposer_acceptor {
24     private:
25         std::mutex proposer_mutex, acceptor_mutex;
26
27         paxos_change *delegate;
28         node_t me;
29
30         rpcs pxs{(in_port_t)std::stoi(me)};
31
32         bool break1 = false;
33         bool break2 = false;
34
35         // Proposer state
36         bool stable = true;
37         prop_t proposal = {0, me};  // number of the last proposal used in this instance
38
39         // Acceptor state
40         prop_t promise = {0, me};   // number of the highest proposal seen in a prepare
41         prop_t accepted = {0, me};  // number of highest proposal accepted
42         value_t accepted_value;     // value of highest proposal accepted
43         unsigned instance_h = 0;    // number of the highest instance we have decided
44         std::map<unsigned,value_t> values;   // vals of each instance
45
46         class log l = {me};
47
48         void commit(unsigned instance, const value_t & v, lock & acceptor_mutex_lock);
49
50         paxos_protocol::status preparereq(prepareres & r, const node_t & src, unsigned instance, prop_t n);
51         paxos_protocol::status acceptreq(bool & r, const node_t & src, unsigned instance, prop_t n, const value_t & v);
52         paxos_protocol::status decidereq(int & r, const node_t & src, unsigned instance, const value_t & v);
53
54         bool prepare(unsigned instance, nodes_t & accepts, const nodes_t & nodes, value_t & v);
55         void accept(unsigned instance, nodes_t & accepts, const nodes_t & nodes, const value_t & v);
56         void decide(unsigned instance, const nodes_t & accepts, const value_t & v);
57
58         void breakpoint1();
59         void breakpoint2();
60
61         // Log a committed paxos instance
62         struct log_instance {
63             unsigned number;
64             string value;
65             MEMBERS(number, value)
66             LABEL("done")
67         };
68
69         // Log the highest proposal number that the local paxos acceptor has
70         // ever seen; called from paxos when responding to preparereq with
71         // accept
72         struct log_proposal {
73             prop_t promise;
74             MEMBERS(promise)
75             LABEL("propseen")
76         };
77
78         // Log the highest proposal (proposal number and value) that the local
79         // paxos acceptor accept has ever accepted; called from paxos when
80         // responding to acceptreq with true
81         struct log_accept {
82             prop_t number;
83             string value;
84             MEMBERS(number, value)
85             LABEL("accepted")
86         };
87
88     public:
89         proposer_acceptor(paxos_change *delegate, bool _first, const node_t & _me, const value_t & _value);
90         unsigned instance() { return instance_h; }
91         const value_t & value(unsigned instance) { return values[instance]; }
92         string dump() { return l.read(); }
93         void restore(const string & s) { l.write(s); l.replay(); }
94         rpcs *get_rpcs() { return &pxs; }
95
96         bool run(unsigned instance, const nodes_t & cnodes, const value_t & v);
97         bool isrunning() { lock ml(proposer_mutex); return !stable; }
98         void breakpoint(int b);
99 };
100
101 #endif