Voting Failure: Timeout

Failure Nodes Over Blocking Number At INIT Stage

Note

blocking number

In voting, to reach a majority for YES, the YES ballots must be over threshold. blocking number is the minimum number to prevent to reach the majority. For example,

  • there are 4 total voters,
  • threshold for majority is 3,

At this condition, blocking number is 2. Simply to say,

blocking number = <voters> - <threshold> + 1
Under situation:
 
  • Suffrage group members should vote for INIT stage.
  • But some nodes does not offer the INIT ballot,
  • The number of these nodes is over blocking number.
  • Timed out in a given time, each node fails to get enough ballots for INIT stage.
Expected actions:
 
  • Each node stops the consensus process and changes its state to Joining.
  • Each node will request *VoteProof* to the others.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
global:
    modules:
        suffrage:
            name: FixedProposerSuffrage
            proposer: n0
nodes:
    n2:
      modules:
          ballot_maker:
              name: ConditionBallotMaker
              conditions:
                  stop:
                      # {
                      #   "ballot": {
                      #     "current_proposal": "sl:7e8sQiEQReVtoe9HcQBfAgNr4V1ZDgx18jpEstuAiA6f",
                      #     "current_round": 0,
                      #     "last_block": "bk:2Xii7H6ykkD58euEHe8DEhAZJPxT3owUEj7EHY9e5HGH",
                      #     "last_round": 0,
                      #     "next_block": "bk:8pyPKQdX78sAe83zq8EoR6NgvfCqRqKNHduBG3xZLHNJ",
                      #     "next_height": 13,
                      #     "stage": "INIT"
                      #   },
                      #   "block": {
                      #     "height": 11,
                      #     "proposal": "sl:8QiEL44ptpYWVgRUxRr9D3KiBYknetonqeJCjHAPD8js",
                      #     "round": 0
                      #   },
                      #   "node": "n3",
                      #   "previousBlock": {
                      #     "height": 10,
                      #     "proposal": "pp:JC5VCGQWagkpSCAXxMa8737LCjkh1gQNkL91jGPmwCjo",
                      #     "round": 11
                      #   },
                      #   "state": "consensus"
                      # }
                      condition: ballot.next_height=13 AND ballot.stage in ("INIT")
                      action: empty-ballot
    n3:
      modules:
          ballot_maker:
              name: ConditionBallotMaker
              conditions:
                  stop:
                      condition: ballot.next_height=13 AND ballot.stage in ("INIT")
                      action: empty-ballot

condition:
    all:
        base_state:
            # {
            #   "level": "info",
            #   "current_state": "booting",
            #   "new_state": "joining",
            #   "m": "state changed"
            # }
            - current_state="booting" AND new_state="joining"
            # {
            #   "level": "info",
            #   "current_state": "joining",
            #   "new_state": "consensus",
            #   "m": "state changed"
            # }
            - current_state="joining" AND new_state="consensus"

        check_majority_accept:
            # {
            #   "level": "debug",
            #   "height": "12",
            #   "round": 0,
            #   "total": 4,
            #   "threshold": 3,
            #   "stage": "ACCEPT",
            #   "set": [
            #     3
            #   ],
            #   "is_finished": true,
            #   "m": "check majority"
            # }
            - m="check majority" AND height=12 AND round=0 AND stage="ACCEPT" AND is_finished=true

        after_failure_state:
            # {
            #   "level": "info",
            #   "current_state": "consensus",
            #   "new_state": "joining",
            #   "m": "state changed"
            # }
            - current_state="consensus" AND new_state="joining"
1
2
3
4
 $ ./contest run failure-voting-init-over-blocking-number.yml \
     --log ./contest-failure-voting-init-over-blocking-number
 $ echo $?
 0

This is the filtered majority checking messages:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
$ cat ./contest-failure-voting-init-over-blocking-number/n0.log | \
     grep -i 'check majority' | \
     jq -c '[.t, .node, .height, .round, .stage, .total, .threshold, .is_finished, .m]' | \
     column -s ',' -t
["11"  0  "INIT"    4  3  false  1     "check majority"]
["11"  0  "INIT"    4  3  false  2     "check majority"]
["11"  0  "INIT"    4  3  true   3     "check majority"]
["11"  0  "SIGN"    4  3  false  1     "check majority"]
["11"  0  "SIGN"    4  3  false  2     "check majority"]
["11"  0  "SIGN"    4  3  true   3     "check majority"]
["11"  0  "SIGN"    4  3  true   null  "check majority    but closed"]
["11"  0  "ACCEPT"  4  3  false  1     "check majority"]
["11"  0  "ACCEPT"  4  3  false  2     "check majority"]
["11"  0  "ACCEPT"  4  3  true   3     "check majority"]
["11"  0  "ACCEPT"  4  3  true   null  "check majority    but closed"]
["12"  0  "INIT"    4  3  false  1     "check majority"]
["12"  0  "INIT"    4  3  false  2     "check majority"]
["12"  0  "INIT"    4  3  true   3     "check majority"]
["12"  0  "SIGN"    4  3  false  1     "check majority"]
["12"  0  "SIGN"    4  3  false  2     "check majority"]
["12"  0  "SIGN"    4  3  true   3     "check majority"]
["12"  0  "SIGN"    4  3  true   null  "check majority    but closed"]
["12"  0  "ACCEPT"  4  3  false  1     "check majority"]
["12"  0  "ACCEPT"  4  3  false  2     "check majority"]
["12"  0  "ACCEPT"  4  3  true   3     "check majority"]
["12"  0  "ACCEPT"  4  3  true   null  "check majority    but closed"]
["13"  0  "INIT"    4  3  false  1     "check majority"]
["13"  0  "INIT"    4  3  false  2     "check majority"]

This shows the node, n0 checks majority on the incoming ballots. As we expected, the voting was done from the block, 11 to 13.

Failure Nodes Under Blocking Number At INIT Stage

Under situation:
 
  • Suffrage group members should vote for INIT stage.
  • But some nodes does not offer the INIT ballot,
  • The number of these nodes is under blocking number.
Expected actions:
 
  • Consensus does not stop.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
global:
    modules:
        suffrage:
            name: FixedProposerSuffrage
            proposer: n0
nodes:
    n3:
      modules:
          ballot_maker:
              name: ConditionBallotMaker
              conditions:
                  stop:
                      # {
                      #   "ballot": {
                      #     "current_proposal": "sl:7e8sQiEQReVtoe9HcQBfAgNr4V1ZDgx18jpEstuAiA6f",
                      #     "current_round": 0,
                      #     "last_block": "bk:2Xii7H6ykkD58euEHe8DEhAZJPxT3owUEj7EHY9e5HGH",
                      #     "last_round": 0,
                      #     "next_block": "bk:8pyPKQdX78sAe83zq8EoR6NgvfCqRqKNHduBG3xZLHNJ",
                      #     "next_height": 13,
                      #     "stage": "INIT"
                      #   },
                      #   "block": {
                      #     "height": 11,
                      #     "proposal": "sl:8QiEL44ptpYWVgRUxRr9D3KiBYknetonqeJCjHAPD8js",
                      #     "round": 0
                      #   },
                      #   "node": "n3",
                      #   "previousBlock": {
                      #     "height": 10,
                      #     "proposal": "pp:JC5VCGQWagkpSCAXxMa8737LCjkh1gQNkL91jGPmwCjo",
                      #     "round": 11
                      #   },
                      #   "state": "consensus"
                      # }
                      condition: ballot.next_height=13 AND ballot.stage in ("INIT")
                      action: empty-ballot

condition:
    all:
        node_state:
            # {
            #   "level": "info",
            #   "current_state": "booting",
            #   "new_state": "joining",
            #   "m": "state changed"
            # }
            - current_state="booting" AND new_state="joining"
            # {
            #   "level": "info",
            #   "current_state": "joining",
            #   "new_state": "consensus",
            #   "m": "state changed"
            # }
            - current_state="joining" AND new_state="consensus"

        check_majority_accept:
            # {
            #   "level": "debug",
            #   "height": "12",
            #   "round": 0,
            #   "total": 4,
            #   "threshold": 3,
            #   "stage": "ACCEPT",
            #   "set": [
            #     3
            #   ],
            #   "is_finished": true,
            #   "m": "check majority"
            # }
            - m="check majority" AND height=12 AND round=0 AND stage="ACCEPT" AND is_finished=true

        check_majority_next_init:
            # {
            #   "level": "debug",
            #   "height": "13",
            #   "round": 0,
            #   "total": 4,
            #   "threshold": 3,
            #   "stage": "INIT",
            #   "set": [
            #     2
            #   ],
            #   "is_finished": true,
            #   "m": "check majority"
            # }
            - m="check majority" AND height=13 AND round=0 AND stage="INIT" AND is_finished=true

        new_block_created:
            # {
            #   "level": "info",
            #   "block": {
            #     "hash": {
            #       "hash": "bk:BoaK2qQSS9qLXDVCtdCG1RA6t5d8JSb73dZLVRCqervp"
            #     },
            #     "height": 12,
            #     "round": 0,
            #     "proposal": {
            #       "hash": "sl:2i1BLweYsSv6egsWooqSigDjvAzhueVv2AKB52wqYkaX"
            #     },
            #     "createdAt": "2019-10-17T13:20:37.258171+09:00"
            #   },
            #   "m": "new block created"
            # }
            - m="new block created" AND block.height=13 AND block.round=0
1
2
3
4
 $ ./contest run failure-voting-init-under-blocking-number.yml \
     --log ./contest-failure-voting-init-under-blocking-number
 $ echo $?
 0

This is the filtered majority checking messages:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
$ cat ./contest-failure-voting-init-over-blocking-number/n0.log | \
     grep -i 'check majority' | \
     jq -c '[.height, .round, .stage, .total, .threshold, .is_finished, .m]' | \
     column -s ',' -t
["11"  0  "INIT"    4  3  false  "check majority"]
["11"  0  "INIT"    4  3  false  "check majority"]
["11"  0  "INIT"    4  3  true   "check majority"]
["11"  0  "SIGN"    4  3  false  "check majority"]
["11"  0  "SIGN"    4  3  false  "check majority"]
["11"  0  "SIGN"    4  3  true   "check majority"]
["11"  0  "SIGN"    4  3  true   "check majority     but closed"]
["11"  0  "ACCEPT"  4  3  false  "check majority"]
["11"  0  "ACCEPT"  4  3  false  "check majority"]
["11"  0  "ACCEPT"  4  3  true   "check majority"]
["11"  0  "ACCEPT"  4  3  true   "check majority     but closed"]
["12"  0  "INIT"    4  3  false  "check majority"]
["12"  0  "INIT"    4  3  false  "check majority"]
["12"  0  "INIT"    4  3  true   "check majority"]
["12"  0  "SIGN"    4  3  false  "check majority"]
["12"  0  "SIGN"    4  3  false  "check majority"]
["12"  0  "SIGN"    4  3  true   "check majority"]
["12"  0  "SIGN"    4  3  true   "check majority     but closed"]
["12"  0  "ACCEPT"  4  3  false  "check majority"]
["12"  0  "ACCEPT"  4  3  false  "check majority"]
["12"  0  "ACCEPT"  4  3  true   "check majority"]
["12"  0  "ACCEPT"  4  3  true   "check majority     but closed"]
["13"  0  "INIT"    4  3  false  "check majority"]
["13"  0  "INIT"    4  3  false  "check majority"]
["13"  0  "INIT"    4  3  true   "check majority"]
["13"  0  "SIGN"    4  3  false  "check majority"]
["13"  0  "SIGN"    4  3  false  "check majority"]
["13"  0  "SIGN"    4  3  true   "check majority"]
["13"  0  "SIGN"    4  3  true   "check majority     but closed"]
["13"  0  "ACCEPT"  4  3  false  "check majority"]
["13"  0  "ACCEPT"  4  3  false  "check majority"]
["13"  0  "ACCEPT"  4  3  true   "check majority"]
["13"  0  "ACCEPT"  4  3  true   "check majority     but closed"]
["14"  0  "INIT"    4  3  false  "check majority"]
["14"  0  "INIT"    4  3  false  "check majority"]
["14"  0  "INIT"    4  3  true   "check majority"]

As the result, the consensus process did not stop, n0 stores the next block, 13.

Failure Of Proposing

Under situation:
 
  • Proposer is selected after INIT stage.
  • Proposer node does not propose the proposal within a given time.
  • Timed out in a given time, each node fails to get the proposal from the proposer.
Expected actions:
 
  • Each node tries to move the next round.
  • Each node broadcasts next INIT ballots for next round.

Failure Of SIGN, ACCEPT Stages

Under situation:
 
  • Suffrage group members should vote for SIGN stage.
  • But some nodes in acting suffrage group does not offer the SIGN ballot.
  • Timed out in a given time, each node fails to get enough ballots for SIGN stage.
Expected actions:
 
  • Each node stops the current vote,
  • Each node broadcasts next INIT ballots for next round.